Пользовательский UIButton выдает несколько ошибок дизайна

Я имею дело с ошибкой XCode, которую я не понимаю, я уже несколько дней ищу решения, и обновление Pods, перезапуск XCode или что-то еще, похоже, не устраняет проблему...

У меня есть собственный класс, который расширяется от UIButton:

import Foundation
import UIKit

//@IBDesignable  <-- COMMENTED BUT SAME ERRORS ... 
class CustomCardButton: UIButton {

    var nibName = "CustomCardButton"

    @IBOutlet weak var btnImageView: UIImageView!
    @IBOutlet weak var btnLabel: UILabel!

    @IBInspectable var image: UIImage? {
        get {
            return btnImageView.image
        } set(image) {
            btnImageView.image = image
        }
    }

    @IBInspectable var label: String? {
        get {
            return btnLabel.text
        } set(label) {
            btnLabel.text = label
        }
    }

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

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

    func setup() {
        let view = loadViewFromNib()
        view.frame = self.bounds
        view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
        btnImageView.layer.cornerRadius = 60/2
        btnImageView.layer.borderColor = UIColor(red: 5/255,
                                                 green: 66/255, blue: 38/255, alpha: 1).CGColor
        btnImageView.layer.borderWidth = 2
        btnLabel.font = UIFont.boldSystemFontOfSize(14.0)
        btnImageView.userInteractionEnabled = true
        btnLabel.userInteractionEnabled = true
        view.userInteractionEnabled = true
        addSubview(view)
    }

    func loadViewFromNib() -> UIButton {
        let bundle = NSBundle(forClass: self.dynamicType)
        let nib = UINib(nibName: nibName, bundle: bundle)
        let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIButton
        return view
    }   
}

Это хорошо скопированный код из SO: работать при нажатии

И мой файл xib выглядит так:

введите здесь описание изображения

На данный момент я сделал это простым, вчера я попробовал его с более сложным (да, 2 метки и изображение, Woooh, сложное для xcode...), и у меня была та же ошибка..

Ошибки:

Предварительная компиляция:

введите здесь описание изображения

После запуска приложения оно вылетает, и у меня есть это:

30 let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIButton
Поток 1: EXC_BAD ACCESS (код = 2, адрес = 0x16fc5bfd0)

31 let view = loadViewFromNib()
Поток 1: EXC_BAD ACCESS (код = 2, адрес = 0x16fc5bfd0)

32 setup()
Поток 1: EXC_BAD ACCESS (код = 2, адрес = 0x16fc5bfd0)

И у меня вылезли эти ошибки с 31 по 2840...

Я видел, что это ошибка XCode, и мы ничего не можем с этим поделать, но мне действительно нужна пользовательская кнопка с двумя метками и ImageVIEW...


person Nicolas Charvoz    schedule 26.05.2016    source источник
comment
попробуйте удалить @IBDesignable   -  person Ravi    schedule 26.05.2016
comment
Вы уверены, что instantiateWithOwner возвращает массив?   -  person    schedule 26.05.2016
comment
Я добавил это: print("BEFORE VIEW ") let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIButton print("VIEW : \(view)" ) И у меня есть цикл BEFORE VIEW, затем он вызывает исключение..   -  person Nicolas Charvoz    schedule 26.05.2016
comment
@NicolasCharvoz Каков класс вашего представления в вашем файле пера? Похоже, что это ваш пользовательский класс CustomCardButton, он сработает в бесконечном цикле, вам нужен файловый менеджер, который будет вашим настраиваемым классом.   -  person oren    schedule 26.05.2016
comment
Его класс CustomCardButton, иначе я бы не смог добавить IBOutlet в класс   -  person Nicolas Charvoz    schedule 26.05.2016
comment
@NicolasCharvoz, это причина сбоя, вам нужен владелец файла (а не менеджер, как я уже говорил :), чтобы он был вашим классом. я опубликую ответ   -  person oren    schedule 27.05.2016


Ответы (1)


Вам нужно, чтобы ваш класс UIView's был просто UIView, а не непосредственно вашим пользовательским классом, в этом случае ваш собственный класс - это File's owner.

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

Перо: Создайте UIView с UIButton в качестве подпредставления (если ваше представление будет каким-то UIView, для которого вы измените его класс на UIButton, ваш IBActions не будет работать, поэтому лучше работать с UIButton в качестве подпредставления)

введите здесь описание изображения

И ваш File's owner — это ваш собственный класс: введите здесь описание изображения

Теперь вы можете перетащить IBOutlets к себе File's owner, удерживая нажатой клавишу CTRL, просто перетащите File's owner, удерживая нажатой клавишу CTRL, к нужному виду:

введите описание изображения здесь введите здесь описание изображения

Вы можете сделать то же самое с IBActions на кнопку

Ваш код немного изменится:

Пользовательский класс, как было сказано, это UIView:

@IBDesignable class CustomCardButton: UIView

А метод loadViewFromNib вернет UIView, а не UIButton:

func loadViewFromNib() -> UIView {
    let bundle = NSBundle(forClass: self.dynamicType)
    let nib = UINib(nibName: nibName, bundle: bundle)
    let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
    return view
}

Вот и все, вы должны увидеть IBDesignable в своей раскадровке:

введите здесь описание изображения

С IBInspectables:

введите здесь описание изображения

person oren    schedule 27.05.2016