Swift:在故事板和大小限制中可重用的UIView

时间:2015-08-18 00:06:35

标签: swift uiview autolayout

我试图在Swift中创建一个可重用的UIView,我可以将其插入到Storyboard视图控制器中。我现在的关键问题是可重复使用的UIView"小部件"并不完全适合故事板中的UIView框。我按照this tutorial设置了可重用的UIView小部件

  1. 创建了UIView的子类和相应的.xib - 并将它们连接起来:

    import UIKit
    
    class MyWidgetView: UIView {
    
    @IBOutlet var view: UIView!;
    
    required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder);
    
    NSBundle.mainBundle().loadNibNamed("MyWidgetView", owner: self, options: nil);
    self.addSubview(self.view);
    }
    
    }
    
  2. 在XIB中,这是与上面代码对应的接口文件,我在模拟度量下使用了自由形式大小的UIView,在视图模式下使用了缩放到填充。

  3. 在主故事板中,我添加了一个UIView块(相同的矩形)并将Class更改为MyWidgetView

  4. 虽然我在XIB和主故事板中都使用了布局约束,但是我在XIB中创建的组件在实际的应用程序中看起来很麻烦。

  5. 查看截图。粉红色的部分不应该出现,因为这只是我在测试尺寸时添加的主要故事板上的UIVIew的颜色。 UIView实际上是MyWidgetView(在我在第3步中更改了类之后)理论上,由于MyWidgetView ==主故事板上的UIView,以及UIView在超视图中具有使其成为矩形的约束,那么为什么我的小部件被压扁了?下面的蓝色部分应该一直向右延伸。Squished widget

2 个答案:

答案 0 :(得分:15)

通过代码添加从代码中的nib文件加载的实际视图层次结构 self.addSubview(self.view)。因此,self.view的框架与其父级实际上没有任何关系,即MyWidgetView

您可以选择通过代码添加布局约束,也可以选择在添加为子视图后设置其框架。就个人而言,我更喜欢后者。在我的实验中,以下内容对我有用。我正在使用Xcode 6.4,我认为它与你的不一样。

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    if let nibsView = NSBundle.mainBundle().loadNibNamed("MyWidgetView", owner: self, options: nil) as? [UIView] {
        let nibRoot = nibsView[0]
        self.addSubview(nibRoot)
        nibRoot.frame = self.bounds
    }
}

答案 1 :(得分:1)

或者,可以覆盖可变帧。当CardImgText设置为视图的文件所有者时,此代码适用于我。

class CardImgTxt: NSView {

    @IBOutlet var view: NSView!
    override var frame: NSRect{
        didSet{
            view.frame = bounds
        }
    }

    override func drawRect(dirtyRect: NSRect) {
        super.drawRect(dirtyRect)


        // Drawing code here.
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        NSBundle.mainBundle().loadNibNamed("View", owner: self, topLevelObjects: nil)
        addSubview(view)
    }

}

如果您对效率比实时更新更感兴趣。然后替换:

    override var frame: NSRect{
        didSet{
            view.frame = bounds
        }
    }

使用:

override func viewDidEndLiveResize() {
    view.frame = bounds
}