Swift:情节提要中的可重用 UIView 和大小限制
Swift: Reusable UIView in storyboard and sizing constraints
我正在尝试在 Swift 中创建一个可重用的 UIView,我可以将它插入到我的 Storyboard 视图控制器中。我现在的关键问题是可重用的 UIView "widget" 不完全适合情节提要中的 UIView 框。我按照 this tutorial 设置了可重复使用的 UIView 小部件
创建了 UIView 的子class 和相应的 .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);
}
}
在上面代码对应的界面文件XIB中,我在Simulated Metrics下使用了UIView with Freeform size,在View模式下使用了Scale to Fill
在主故事板中,我添加了一个 UIView 块(相同的矩形)并将 Class 更改为 MyWidgetView
它有效,但我在 XIB 中创建的组件在实际应用程序中看起来被压扁了,尽管我在 XIB 和主故事板中都使用了布局约束。
见截图。粉红色部分不应该出现,因为它只是我为测试大小而添加的主故事板上 UIVIew 的一种颜色。那个 UIView 实际上是 MyWidgetView(在我在第 3 步中更改 class 之后。所以理论上,由于 MyWidgetView == 主故事板上的 UIView,并且 UIView 具有使其在超级视图中成为矩形的约束,那么为什么我的小部件被压扁了?下面的蓝色部分应该一直向右延伸。
从代码中的 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
}
}
或者可以覆盖变量框架。当 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
}
我正在尝试在 Swift 中创建一个可重用的 UIView,我可以将它插入到我的 Storyboard 视图控制器中。我现在的关键问题是可重用的 UIView "widget" 不完全适合情节提要中的 UIView 框。我按照 this tutorial 设置了可重复使用的 UIView 小部件
创建了 UIView 的子class 和相应的 .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); } }
在上面代码对应的界面文件XIB中,我在Simulated Metrics下使用了UIView with Freeform size,在View模式下使用了Scale to Fill
在主故事板中,我添加了一个 UIView 块(相同的矩形)并将 Class 更改为 MyWidgetView
它有效,但我在 XIB 中创建的组件在实际应用程序中看起来被压扁了,尽管我在 XIB 和主故事板中都使用了布局约束。
见截图。粉红色部分不应该出现,因为它只是我为测试大小而添加的主故事板上 UIVIew 的一种颜色。那个 UIView 实际上是 MyWidgetView(在我在第 3 步中更改 class 之后。所以理论上,由于 MyWidgetView == 主故事板上的 UIView,并且 UIView 具有使其在超级视图中成为矩形的约束,那么为什么我的小部件被压扁了?下面的蓝色部分应该一直向右延伸。
从代码中的 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
}
}
或者可以覆盖变量框架。当 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
}