Есть ли способ получить родительский объект из подпредставления? - PullRequest
2 голосов
/ 08 апреля 2019

Я работаю над приложением кроссвордов для swift и у меня возникают проблемы с получением UIButton от subview в UIButton, то есть textfield.

Текстовое поле занимает место, где должен быть заголовок UIButton, но при нажатии на textfield оно не щелкает по UIButton. Сам UIButton на данный момент выделяет все UIButtons некоторого столбца и строки.

Я попробовал несколько вещей, таких как создание суперкласса подпредставления

var myButton: CustomButton = textfield.superclass as? CustomButton

и я тоже пытался использовать

var myObject : CustomButton? {
  return view.compactMap({$0 as? CustomButton }).first
}

В CustomButton.swift

class CustomButton: UIButton {
    var number: Int = 0
    var letter: Character?
    var textField: UITextField!
    var cornerLabel: UILabel!

    // this init will intialize the button through programatically
    override init(frame: CGRect) {
        super.init(frame: frame)

        textField = UITextField(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
        textField.translatesAutoresizingMaskIntoConstraints = false
        textField.center = .zero
        textField.textAlignment = .center
        textField.text = ""

У меня есть ButtonStore.swift, в котором хранятся все пользовательские кнопки в массиве, поэтому я могу управлять ими и извлекать определенные.

И MainController.swift имеет все ссылки CustomButton. Я использую UITextFieldDelegate из MainController

class MainController : UIViewController, UITextFieldDelegate{
    var buttonStore : ButtonStore!

    @IBOutlet var A1 : CustomButton!

    @IBAction func buttonIsPress(sender: CustomButton){
        let button : CustomButton = sender
        let identifier : String = sender.accessibilityIdentifier ?? ""
        // Clear all backgroundbox back to white unless the background is black
        buttonStore.removeHighlights()
        // Highlight the button pressed and its column and row
        buttonStore.highlightRowColumn(identifier: identifier)
    }

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool 
    {
        print("something happened")
        // TRIED RECEIVING THE CUSTOMBUTTON HERE
        return true
    }

Ожидаемый результат должен иметь триггер CustomButton при нажатии текстового поля или захват CustomButton нажатой текстового поля, поэтому я использую CustomButton в качестве ссылки.

Ответы [ 2 ]

1 голос
/ 08 апреля 2019

Вы можете получить любой суперпредставление или любой родительский контроллер представления в общем виде безопасным способом, пройдя по цепочке респондента (поскольку UIViewController и UIView наследуют от UIResponder и реализуют его метод next):

extension UIResponder {
    func firstParent<T: UIResponder>(ofType type: T.Type ) -> T? {
        return next as? T ?? next.flatMap { $0.firstParent(ofType: type) }
    }
}

Используйте как:

if let button = textField.firstParent(ofType: CustomButton.self) {
  //Do button stuff here
}

Этот метод имеет то преимущество, что вы можете найти следующего родителя определенного типа, даже если он не является непосредственным родителем (то есть у вас может быть несколько представлений между текстовым полем и CustomButton, и это все еще работает, в то время как вызов superview делает нет).

1 голос
/ 08 апреля 2019

Вы можете получить superview по

if let button = textField.superview as? CustomButton {
   // Do what you want to here
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...