Связь между UIView и UIViewController по протоколу не работает - PullRequest
0 голосов
/ 10 октября 2018

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

У меня естьследующий UIView:

import UIKit

protocol DetailViewWillShowUpDelegate {
    func sendDetailOpened(_ openedBool: Bool)
}

class locationXIBController: UIView {

    @IBOutlet weak var loationLabel: UILabel!
    @IBOutlet weak var vsedniOteviraciDobaLabel: UILabel!
    @IBOutlet weak var prijmajiKartyLabel: UILabel!
    @IBOutlet weak var detailViewButtonOutlet: UIButton!
    @IBOutlet weak var backgroundViewButton: UIButton!

    let openedBool = true
    var detailViewWillShowUpDelegate: DetailViewWillShowUpDelegate?

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    @IBAction func vecerkaDetailButtonPressed(_ sender: UIButton) {
        detailViewWillShowUpDelegate?.sendDetailOpened(openedBool)
        print("pressed")
    }

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        if let result = detailViewButtonOutlet.hitTest(convert(point, to: detailViewButtonOutlet), with: event) {
            return result
        }
        return backgroundViewButton.hitTest(convert(point, to: backgroundViewButton), with: event)
    }

}

Теперь проблема в том, что когда я вызываю / нажимаю функцию vecerkaDetailButtonPressed, я получаю «нажатие» на выход в консоли, но протокол по какой-то причине не проходит через,

Другая сторона выглядит следующим образом (для простоты):

class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

    let locationXIB = locationXIBController()
    let isVecerkaDetailOpened = false

    override func viewDidLoad() {
       locationXIB.detailViewWillShowUpDelegate = self
    }



extension MapViewController: DetailViewWillShowUpDelegate {
    func sendDetailOpened(_ openedBool: Bool) {
        isVecerkaDetailOpened = openedBool
        print("success")
    }
}

Я знаю, что значение протокола на момент выполнения равно нулю.Как я уже сказал, любая помощь приветствуется, спасибо!

Ответы [ 4 ]

0 голосов
/ 11 октября 2018

Ответ на кредит @ Paulw11

Мне, наконец, удалось заставить его работать, общаясь так:

шаг 1) 1: 1 связь по протоколу между MKAnnotation и MKAnnotationView

шаг 2) 1: 1 обмен данными по протоколу между MKAnnotationView и MapViewController с передачей одних и тех же данных

Наконец-то работает как чудо, спасибо!

0 голосов
/ 10 октября 2018

В дополнение к ответу @Duncan C, вы можете проверить, нужен ли вам super.viewDidLoad() в начале метода viewDidLoad() в классе MapViewController?Невыполнение этого может привести к странным вещам в вашем приложении.

0 голосов
/ 10 октября 2018

Я спросил:

Так что detailViewWillShowUpDelegate на самом деле указывает на что-нибудь, или это ноль?

И вы ответили:

Я только что попробовал отладку, и это на самом деле nil

Так вот в чем проблема ... вам нужно установить detailViewWillShowUpDelegate, чтобы указать на действительный объект делегата.Это часто делается в файле .xib или раскадровке, и иногда люди забывают установить это соединение, поэтому проверьте, имеет ли это смысл.Иначе вам просто нужно получить ссылку на делегата в какой-то момент, прежде чем соответствующий код сможет его запустить и настроить.

0 голосов
/ 10 октября 2018

Во-первых, несколько проблем с соглашением об именах:

Имя locationXIBController - неправильный выбор для объекта UIView.Это объект просмотра, а не объект контроллера.

Во-вторых, имена классов в Swift должны начинаться с заглавной буквы.Так что LocationXIBView было бы гораздо лучшим именем для этого класса представления.

Далее, ваш код

let locationXIB = locationXIBController()

... неверен.Это создает совершенно новый экземпляр вашего класса locationXIBController, который вы никогда не устанавливаете в своей иерархии представлений.Вы должны сделать эту линию IBOutlet:

@IBOutlet weak var locationXIB: locationXIBController!

А затем вы должны перетащить управление с locationXIBController в вашей StoryBoard на розетку в вашем контроллере представления.Это заставит Interface Builder подключить розетку.

Теперь, когда вы запустите свою программу, переменная locationXIB будет подключена к представлению locationXIBController из вашей раскадровки / XIB при загрузке.

...