2015-08-18 2 views
6

Я пытаюсь создать многократно используемый UIView в Swift, который я могу подключить к своим контроллерам просмотра Storyboard. Моя ключевая проблема прямо сейчас заключается в том, что многопользовательский «виджет» UIView не полностью вписывается в поле UIView в раскадровке. Я последовал this tutorial настроить многоразовый UIView виджетSwift: многоразовый 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 с размером Freeform в режиме Simulated Metrics и Scale to Fill under View.

  3. В главном раскадровку, я добавил UIView блок (такой же прямоугольной формы) и изменил класс для MyWidgetView

  4. Он работает, но компоненты я создал в XIB взгляд сплющенные в самом приложении, несмотря на тот факт, что я использовал ограничения компоновки как в XIB, так и в основной раскадровке.

Посмотреть скриншот. Розовая часть не должна появляться, так как это только цвет UIVIew на главной раскадровке, которую я добавил, чтобы проверить размер. Этот UIView на самом деле является MyWidgetView (после того, как я изменил класс на шаге 3. Итак, теоретически, поскольку MyWidgetView == UIView на главной раскадровке и что UIView имеет ограничения, которые делают его прямоугольным в супервизоре, тогда почему мой виджет сжимается? синяя часть ниже должна распространяться весь путь правильный. Squished widget

ответ

14

фактическая иерархия вид загружается из файла СИБ в коде добавляется через 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 
    } 
} 
+0

Хорошо, я попробую это. У меня XCode 7 beta 5 и Swift 2.0, поэтому я могу загружать приложения на своем устройстве, не переходя через подписку Apple на 99 долларов. –

+0

Впечатляющий ... это работает. Можете ли вы объяснить немного больше, как это работает? Особенно вокруг «nibRoot» - не уверен, что я полностью понимаю эту часть. –

+2

Рад, что это работает! Как описано в [официальном документе] (https://developer.apple.com/library/ios/documentation/UIKit/Reference/NSBundle_UIKitAdditions/#//apple_ref/occ/instm/NSBundle/loadNibNamed :owner:options :), возвращаемое значение 'NSBundle.loadNibNamed()' is ** Массив, содержащий объекты верхнего уровня в файле nib **.В нашем случае есть только один объект верхнего уровня: вид, содержащий всю вашу иерархию представлений 'MyWidgetView'. Итак, после успешного вызова 'loadNibNamed' мы выбрали первое и единственное представление как' nibRoot' и добавили его как подвью. – southp

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 
} 
Смежные вопросы