Swift: многоразовый UIView в раскадровках и ограничениях размеров
Я пытаюсь создать повторно используемый UIView в Swift, который я могу подключить к моим контроллерам представлений раскадровки. Моя ключевая проблема прямо сейчас заключается в том, что многопользовательский "виджет" UIView не полностью вписывается в поле UIView в раскадровке. Я выполнил этот учебник, чтобы настроить виджет UIView для повторного использования
-
Создал подкласс 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);
}
}
-
В XIB, который является файлом интерфейса, соответствующим указанному выше коду, я использовал UIView с размером свободной формы в режиме "Моделируемые показатели" и "Масштаб для заполнения в режиме просмотра".
-
В основной раскадровке я добавил блок UIView (ту же прямоугольную форму) и изменил класс на MyWidgetView
-
Он работает, но компоненты, которые я создал в XIB, выглядят в реальном приложении, несмотря на то, что я использовал ограничения компоновки как в XIB, так и в главной раскадровке.
Смотрите скриншот. Розовая часть не должна появляться, так как это только цвет UIVIew на главной раскадровке, которую я добавил, чтобы проверить размер. Этот UIView на самом деле является MyWidgetView (после того, как я изменил класс на шаге 3. Итак, теоретически, поскольку MyWidgetView == UIView на главной раскадровке и что UIView имеет ограничения, которые делают его прямоугольным в супервизоре, тогда почему мой виджет сжимается? Синяя часть внизу должна полностью простираться. ![Скважинный виджет]()
Ответы
Ответ 1
Иерархия фактического представления, загруженная из файла 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
}
}
Ответ 2
В качестве альтернативы переменный фрейм может быть переопределен. Этот код работал у меня, когда 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
}