如何在drawRect中获取UIView大小

问题描述 投票:2回答:3

我正在使用self.bound来获取drawRect方法中的UIView大小。但是现在,使用XCode 9,我收到了这个警告:

主线程检查器:在后台线程上调用UI API: - [UIView bounds]

drawRect方法中获取视图大小的正确方法是什么?

ios objective-c iphone uikit ios11
3个回答
6
投票

像这样:

override func drawRect(rect: CGRect)
    let bds = DispatchQueue.main.sync {
        return self.bounds
    }
    // ....
}

但是drawRect首先在后台线程上被调用的事实是一个坏迹象 - 除非你使用CATiledLayer或其他一些内置架构来做到这一点。你应该首先担心这一点。


5
投票

我终于找到了问题的解决方案。我现在重写UIView的layoutSubviews以保持类成员中的视图边界:

- (void)layoutSubviews
{
    [super layoutSubviews];
    m_SelfBounds = self.bounds;
}

在那之后,我只是在m_SelfBounds方法中使用drawRect


0
投票

使用Grand Central Dispatch的“屏障”功能允许并发读取操作,同时在写入期间阻止这些操作:

class MyTileView: UIView
{
  var drawBounds = CGRect(x: 0, y: 0, width: 0, height: 0)
  let drawBarrierQueue = DispatchQueue(label: "com.example.app",
                                             qos: .userInteractive, // draw operations require the highest priority threading available
                                             attributes: .concurrent,
                                             target: nil)

  override func layoutSubviews() {
    drawBarrierQueue.sync(flags: .barrier) { // a barrier operation waits for active operations to finish before starting, and prevents other operations from starting until this one has finished
      super.layoutSubviews();

      self.drawBounds = self.bounds

      // do other stuff that should hold up drawing
    }
  }

  override func draw(_ layer: CALayer, in ctx: CGContext)
  {
    drawBarrierQueue.sync {
      // do all of your drawing

      ctx.setFillColor(red: 1.0, green: 0, blue: 0, alpha: 1.0)
      ctx.fill(drawBounds)
    }
  }
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.