Взаимодействие с UITableView в подпредставлении - PullRequest
0 голосов
/ 25 июня 2019

Я встроил tableView в суперпредставление Custom UITextfield. Табличное представление должно отображать результаты в представлении, что означает, что я хочу иметь возможность прокрутить и выбрать ячейку в табличном представлении. Отображается табличное представление, но я не могу прокрутить или выбрать ячейку tableView.

Вот как визуализируется tableView с помощью поля UITex.

UITexfield расширен

override init(frame: CGRect) {
        super.init(frame: frame)
        shared()
        commonInit()
        if let superview = superview {
            setupAutocompleteTable(superview)
        }
    }

    public override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        commonInit()
        setupAutocompleteTable(newSuperview!)

    }
    lazy var tableView: UITableView = {
        let tableView = UITableView()
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.dataSource = self
        tableView.delegate = self
        tableView.rowHeight = autoCompleteCellHeight
        tableView.isHidden = hidesWhenEmpty ?? true
        tableView.layer.borderColor = UIColor.lightGray.cgColor
        tableView.layer.borderWidth = 0.5
        tableView.layer.zPosition = CGFloat(Float.greatestFiniteMagnitude)
        return tableView
    }()

    fileprivate func setupAutocompleteTable(_ view: UIView) {

        autoCompleteTableMargin = 10.0

        view.addSubview(tableView)
        tableView.topAnchor.constraint(equalTo: view.bottomAnchor, constant: 20).isActive = true
        tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        tableView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
        tableView.heightAnchor.constraint(equalToConstant: 30).isActive = true

        autoCompleteTableView = tableView
        autoCompleteTableHeight = 200.0
    }

ViewController

lazy var searchField: GooglePlaceSearchField = {
        let field = GooglePlaceSearchField()
        field.translatesAutoresizingMaskIntoConstraints = true
        field.placeholder = "Enter area, city .."
        field.setIcon(#imageLiteral(resourceName: "zamasearch"))
        field.highLightTypeTextedEnabled = true
        return field
    }()

    view.addSubview(searchBgView)
    searchBgView.addSubview(searchField)

любая помощь о том, как взаимодействовать с tableView

ограничения searchField

searchBgView.anchor(top: view.safeAreaLayoutGuide.topAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 14, paddingLeft: 20, paddingBottom: 0, paddingRight: 20, width: 0, height: 50, enableInsets: false)
        searchField.anchor(top: searchBgView.topAnchor, left: searchBgView.leftAnchor, bottom: searchBgView.bottomAnchor, right: iconContainerView.leftAnchor, paddingTop: 00, paddingLeft: 20, paddingBottom: 0, paddingRight: 0, width: 0, height: 0, enableInsets: false)

1 Ответ

1 голос
/ 25 июня 2019

Изменить:

После перечитывания вопроса и последующих комментариев tableView добавлялся в textField в качестве родственного брата ... но проблема та же. TableView вне границ своего суперпредставления.

Этот пример все еще можно использовать в качестве отправной точки для обработки проверки попадания в «фоновом режиме поиска» (или использовать таблицу в качестве подпредставления поля, как показано здесь).


Вот краткий пример, который вы сможете использовать в качестве основы для своего настраиваемого поля / источника данных.

Если вы закомментируете функцию hitTest(...), вы увидите таблицу, но не сможете с ней взаимодействовать.

Примечание: Это всего лишь пример кода, который поможет вам в пути - его нельзя считать готовым к работе.

class MyCustomTextField: UITextField {

    lazy var tableView: UITableView = {
        let tableView = UITableView()
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.dataSource = self
        tableView.delegate = self
        tableView.layer.borderColor = UIColor.lightGray.cgColor
        tableView.layer.borderWidth = 0.5
        tableView.layer.zPosition = CGFloat(Float.greatestFiniteMagnitude)
        return tableView
    }()

    let theData = [ "A", "B", "C", "D", "E", "F", "G", "H", "I" ]

    // if we comment-out this func, we will NOT be able to interact with the tableView
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

        guard isUserInteractionEnabled else { return nil }

        guard !isHidden else { return nil }

        guard alpha >= 0.01 else { return nil }

        let convertedPoint = tableView.convert(point, from: self)
        if let v = tableView.hitTest(convertedPoint, with: event) {
            return v
        }

        guard self.point(inside: point, with: event) else { return nil }

        return self
    }


    override init(frame: CGRect) {
        super.init(frame: frame)
        setupAutocompleteTable(self)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    public override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        setupAutocompleteTable(self)
    }

    fileprivate func setupAutocompleteTable(_ view: UIView) {
        if tableView.superview == nil {
            view.addSubview(tableView)
            tableView.topAnchor.constraint(equalTo: view.bottomAnchor, constant: 20).isActive = true
            tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
            tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
            tableView.heightAnchor.constraint(equalToConstant: 200).isActive = true

            tableView.register(UITableViewCell.self, forCellReuseIdentifier: "TheCell")
        }
    }

}

extension MyCustomTextField: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return theData.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TheCell", for: indexPath)
        cell.textLabel?.text = theData[indexPath.row]
        return cell
    }
}

extension MyCustomTextField: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.text = theData[indexPath.row]
    }
}

class TextFieldSubViewController: UIViewController {

    let customTextField: MyCustomTextField = {
        let v = MyCustomTextField()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.borderStyle = .roundedRect
        v.backgroundColor = .yellow  // makes it easy to see
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(customTextField)

        NSLayoutConstraint.activate([
            customTextField.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 40.0),
            customTextField.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 40.0),
            customTextField.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -40.0),
            ])

    }

}

Результат:

enter image description here


Редактировать 2:

Вот еще один быстрый пример, использующий «вид фона поиска» с UITextField, UIButton и UITableView в качестве подпредставлений (братья и сестры друг друга). Представление таблицы будет отображаться / скрываться, когда текстовое поле начинается / заканчивается редактированием.

class CustomSearchView: UIView {

    lazy var theTextField: UITextField = {
        let v = UITextField()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.borderStyle = .roundedRect
        v.delegate = self
        return v
    }()

    lazy var tableView: UITableView = {
        let tableView = UITableView()
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.dataSource = self
        tableView.delegate = self
        tableView.layer.borderColor = UIColor.lightGray.cgColor
        tableView.layer.borderWidth = 0.5
        tableView.layer.zPosition = CGFloat(Float.greatestFiniteMagnitude)
        return tableView
    }()

    let doneButton: UIButton = {
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.setTitle("Done", for: .normal)
        v.setTitleColor(.blue, for: .normal)
        return v
    }()

    let theData = [ "A", "B", "C", "D", "E", "F", "G", "H", "I" ]

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    func commonInit() -> Void {

        addSubview(theTextField)
        addSubview(doneButton)
        addSubview(tableView)

        NSLayoutConstraint.activate([

            doneButton.topAnchor.constraint(equalTo: topAnchor, constant: 4.0),
            doneButton.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -4.0),
            doneButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8.0),

            theTextField.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8.0),
            theTextField.trailingAnchor.constraint(equalTo: doneButton.leadingAnchor, constant: -8.0),
            theTextField.centerYAnchor.constraint(equalTo: doneButton.centerYAnchor),

            tableView.topAnchor.constraint(equalTo: theTextField.bottomAnchor, constant: 8.0),
            tableView.leadingAnchor.constraint(equalTo: theTextField.leadingAnchor, constant: 0.0),
            tableView.trailingAnchor.constraint(equalTo: theTextField.trailingAnchor, constant: 0.0),

            tableView.heightAnchor.constraint(equalToConstant: 200.0),

            ])

        doneButton.setContentHuggingPriority(.required, for: .horizontal)

        doneButton.addTarget(self, action: #selector(doneTapped), for: .touchUpInside)

        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "TheCell")

        tableView.isHidden = true

    }

    @objc func doneTapped() -> Void {
        self.endEditing(true)
    }

    // if we comment-out this func, we will NOT be able to interact with the tableView
    // Note: this hitTest func based on source here: http://khanlou.com/2018/09/hacking-hit-tests/
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

        guard isUserInteractionEnabled else { return nil }

        guard !isHidden else { return nil }

        guard alpha >= 0.01 else { return nil }

        for subview in subviews.reversed() {
            let convertedPoint = subview.convert(point, from: self)
            if let candidate = subview.hitTest(convertedPoint, with: event) {
                return candidate
            }
        }

        guard self.point(inside: point, with: event) else { return nil }

        return self
    }

}

extension CustomSearchView: UITextFieldDelegate {
    func textFieldDidBeginEditing(_ textField: UITextField) {
        tableView.isHidden = false
    }
    func textFieldDidEndEditing(_ textField: UITextField) {
        tableView.isHidden = true
    }
}

extension CustomSearchView: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return theData.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TheCell", for: indexPath)
        cell.textLabel?.text = theData[indexPath.row]
        return cell
    }
}

extension CustomSearchView: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.theTextField.text = theData[indexPath.row]
    }
}


class TextFieldSubViewController: UIViewController {

    let customSearchView: CustomSearchView = {
        let v = CustomSearchView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .lightGray
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(customSearchView)

        NSLayoutConstraint.activate([
            customSearchView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0.0),
            customSearchView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0.0),
            customSearchView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 0.0),
            ])

    }

}

Результат:

enter image description here


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