2017-04-03 62 views
1

我使用下面的代码来强制UIView一个子类从XIB文件,其名称是实际的类名加载实例:确定是否`UIView`从厦门国际银行加载或代码

class NibView : UIView { 
    override func awakeAfter(using aDecoder: NSCoder) -> Any? { 
     guard isRawView() else { return self } 
     for view in self.subviews { 
      view.removeFromSuperview() 
     } 

     let view = instanceFromNib() 
     return view 
    } 

    func isRawView() -> Bool { 
     // What here? 
    } 
} 

目的isRawView()方法的目的是确定此视图是从代码创建的,还是从相应的XIB文件加载的。 到目前为止我使用的实现是:

func isRawView() -> Bool { 
    // A subview created by code (as opposed to being deserialized from a nib) 
    // has 2 subviews, both implementing the `UILayerSupport` protocol 
    return 
     self.subviews.count == 2 && 
     self.subviews.flatMap(
      { $0.conforms(to: UILayoutSupport.self) ? $0 : nil }).count == 2 
} 

它使用一招,以确定该视图是从代码创建,因为在这种情况下,它精确地包含2子视图,既实现UILayoutSupport协议。

当从代码实例化NibView子类时,此功能很好。但是如果视图是在故事板(并且大概从XIB文件加载的视图控制器和视图可能会发生同样的情况)中创建为视图控制器的一部分,则它不起作用。

解释我的问题的原因的长篇故事:有没有办法让UIView知道它是否已从XIB文件加载,并且可能是该文件的名称?中,或者实施isRawView()方法的另一种方式即应:

  • 回报false如果视图已经从相关的XIB文件(文件名是类名)true否则
  • 返回反序列化

回答

0

利用提供的init函数。

示例代码:

override init(frame: CGRect) { 
    super.init(frame: frame) 
    print("From code") 
} 

required public init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 
    print("From nib") 
} 

我可以打印出的类名称是这样的:

print(NSStringFromClass(type(of: self)).components(separatedBy: ".").last ?? "Couldn't get it") 

您应该可以使用该功能,或许稍作调整即可获得所需的功能。

+0

这可以帮助我区分代码和xib,但我认为它不会告诉我哪个xib已被使用。 – Antonio

+0

@Antonio;我用一些可以打印类名的代码更新了我的答案。 – Hodson

+0

这是xib文件名,而不是我正在寻找的类名。 'super.init(coder:aDecoder)'在内部调用'awakeAfter(using:)',并且在该方法中,我需要确定当前视图是否已从名称为类名的xib文件加载。 – Antonio

相关问题