Есть ли способ получить родительский объект из подпредставления?

Я работаю над приложением для кроссвордов для 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, в котором хранятся все CustomButtons в массиве, поэтому я могу управлять ими и извлекать определенные.

И у 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 в качестве ссылки.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

if let button = textField.superview as? CustomButton {
   // Do what you want to here
}

Ого, это было проще, чем я ожидал. Я не знал, что вы можете изменить супервизор как объект. Большое спасибо.

Randy Le 08.04.2019 20:00

@RandyLeRandy Удовольствие, пожалуйста, примите ответ, если он решил вашу проблему.

Razi Tiwana 08.04.2019 22:36

Вы можете захватить любой суперпредставление или любой контроллер родительского представления в целом безопасным способом, пройдя вверх по цепочке респондентов (поскольку и 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 — нет).

большое спасибо, я рассмотрю это, когда у меня будет дополнительное время, когда мне нужно будет управлять большим количеством подвидов.

Randy Le 08.04.2019 21:20

Другие вопросы по теме