доступ к подклассу UIView в контроллере представления - PullRequest
2 голосов
/ 07 февраля 2020

Допустим, у меня есть SomeViewController: UIViewController, и у меня есть пользовательское представление CustomView: UIView, определенное как XIB, которое я хочу отобразить. Это пользовательское представление будет повторно использовано в других контроллерах представления и даже несколько раз в одном контроллере представления.

class CustomView: UIView {
  @IBOutlet public var label: UILabel!
}

Способ, которым я всегда добавлял это представление, был:

class UIExamples: UIViewController {
  @IBOutlet private var myView: UIView!

  override func viewDidLoad() {
    super.viewDidLoad()
    // Assume makeViewFromNib returns the view [0] in the Nib. 
    let customView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
    customView.frame = myView.bounds
    myView.addSubview(customView)
  }
}

Предположим, что позже я захочу что-то изменить в CustomView через публичные c свойство label.

Я мог бы сделать это внутри viewDidLoad ТОЛЬКО ПОТОМУ ЧТО У меня есть доступ к customView, но что если я захочу изменить его в какой-нибудь другой функции? Что я видел, так это то, что нужно было бы сделать

let customView = myView.subviews[0] as! CustomView
customView.label.text = "some text"

, что выглядит неправильно.

Итак, я подумал, что правильный путь должен быть таким:

class UIExamples: UIViewController {
  @IBOutlet public var customView: CustomView! // Now this is always a CustomView type

  override func viewDidLoad() {
    super.viewDidLoad()

    // Assume makeViewFromNib returns the view [0] in the Nib. 
    customView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
    customView.label.text = "some text" // DOES NOT WORK!
  }
}

Эта последняя строка customView.label.text не работает. На самом деле ярлык даже не виден на экране. Что я делаю неправильно?

Ответы [ 2 ]

0 голосов
/ 10 февраля 2020

Отправляю свой ответ.

  1. Создайте файл XIB.
  2. Создание файла Swift подкласса UIView.
  3. В поле пользовательского класса Identify Inspector владельца XIB введите имя подкласса UIView (ваше пользовательское представление).
  4. В инспекторе подключений владельца файла XIB убедитесь, что все IBOutlets в файле Swift подключены.
  5. Добавьте представление в контроллер представления и в его пользовательском типе класса Identify Inspector укажите имя пользовательского класса.

Важно: * В вашем файле XIB swift вы должны правильно загрузить представление содержимого XIB.

...

  /// Initializer used by Interface Builder.
  required init?(coder: NSCoder) {
    super.init(coder: coder)
    configure()
  }

  /// Initializer used programmatically.
  override init(frame: CGRect) {
    super.init(frame: frame)
    configure()
  }

...

func configure() {
  let contentView = // here use many of the functions available on the internet to 
                    // load a view from a nib. 
  // Then add this view to the view hierarchy. 
    addSubview(contentView)
}
0 голосов
/ 07 февраля 2020

ОК, не читал (или, возможно, читал перед редактированием), что вы используете xib. Если ViewController создан из xib с меткой, это будет правильным способом:

установить класс myView в xib здесь:

xib view screenshot

и затем подключите IBOutlet (удалите текущий из xib здесь:

outlets screenshot

и затем из кода).

Теперь myView.label.text = "some text" должен работать без дальнейших проблем. Удачи!


Если вы создаете свое представление из кода, сделайте это следующим образом:

class UIExamples: UIViewController {
  @IBOutlet private var myView: CustomView!

  override func viewDidLoad() {
    super.viewDidLoad()
    // Assume makeViewFromNib returns the view [0] in the Nib. 
    myView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
    myView.frame = view.bounds
    view.addSubview(myView)
  }
}

Поскольку у вас уже есть свойство, хранящее это представление в контроллере представления, копать не нужно внутри подпредставлений это будет работать так:

myView.label.text = "some text"

И причина того, что

customView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
    customView.label.text = "some text"

не работает, в том, что это совершенно новый вид, который не был добавлен в ваш вид. Контроллеры (также кадр не был установлен, кстати). И поскольку вы изменили значение своего свойства customView, оно теперь не указывает на старый экземпляр представления, который присутствует в подпредставлениях (вы все еще можете видеть этот «старый», но не изменять его).

Но я очень рекомендую использовать указатель, созданный один раз, как правильный класс, чтобы избежать приведения. (Или создание представления непосредственно в xib / storyboard, иначе @IBOutlet не требуется)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...