当在其他 UIBarButtonItem 中使用相同的子视图时,我在 UIBarButtonItem 中的 customView 的子视图消失

Subview of my customView in UIBarButtonItem disappear when using the same subview in other UIBarButtonItem

这就是我自定义 UIBarButtonItem 的方式:

if DBAppSettings.imageViewForCartBarButtonItem == nil {
    DBAppSettings.imageViewForCartBarButtonItem = UIImageView(frame: CGRectMake(5, 5, 30, 30))
    DBAppSettings.imageViewForCartBarButtonItem.backgroundColor = UIColor.greenColor()
}

let wrapperView = UIView(frame: CGRectMake(0, 0, 40, 40))
wrapperView.backgroundColor = UIColor.yellowColor()

wrapperView.addSubview(DBAppSettings.imageViewForCartBarButtonItem)
let cartBarButtonItem = UIBarButtonItem(customView: wrapperView)

设置好 UIBarButtonItem 后,它看起来不错:

但是当我从导航堆栈中按下然后弹出视图控制器(这意味着我使用相同的绿色子视图将其加载到另一个 UIBarButtonItem)时,它是黄色的。看起来绿色子视图已被释放。为什么?

这就是我保持对绿色子视图的引用的方式:

class DBAppSettings: NSObject {
    static var imageViewForCartBarButtonItem: UIImageView!
}

:

一切正常,当我在本地保留绿色子视图时:

let green = UIImageView(frame: CGRectMake(5, 5, 30, 30))
green.backgroundColor = UIColor.greenColor()

wrapperView.addSubview(green)

正如我在评论中所写。 UIView 可以只有一个超级视图。如果您第二次将它添加为子视图,它将从第一个超级视图中删除,然后添加到新的超级视图中。检查 addSubview... 文档:

Views can have only one superview. If view already has a superview and that view is not the receiver, this method removes the previous superview before making the receiver its new superview.

它没有被释放。它刚刚从您的第一个 wrapperView.

中删除

您可以使用自定义工厂方法,如下所示:

extension UIBarButtonItem {

  static func myBarButtonItem() -> UIBarButtonItem {
    let imageView = UIImageView(frame: CGRectMake(5,5,30,30))
    imageView.backgroundColor = UIColor.greenColor()

    let wrapperView = UIView(frame: CGRectMake(0, 0, 40, 40))
    wrapperView.backgroundColor = UIColor.yellowColor()
    wrapperView.addSubview(imageView)

    return UIBarButtonItem(customView: wrapperView)
  }

}

即使用UIImage也不怕。 UIImages被缓存,共享,...一个图像在内存中不是多次,只有一次。谈论 UIImage & init?(named name: String).

在每个 UIViewController 中,只需使用 UIBarButtonItem.myBarButtonItem()wrapperViewimageView 和一个 UIImage.

的多个实例