Swift, ioutlet и настраиваемые элементы управления

Возможно, я делаю что-то действительно глупое, но, похоже, я не могу использовать Interface Builder для подключения переменных IBOutlet к пользовательским представлениям, но только в Swift.

Я создал класс под названием MyView, который расширяется от UIView. В моем контроллере есть переменная MyView (объявленная как @IBOutlet var newView: MyView). Я захожу в IB и перетаскиваю UIView в окно и присваиваю ему класс MyView.

Всякий раз, когда я делал подобное в Objective C, я мог нажать кнопку View Controller в верхней части окна приложения, выбрать переменную и перетащить ее вниз к элементу управления, чтобы связать их вместе. Когда я пробую это в Swift, он отказывается распознавать наличие представления.

Если я изменю класс переменной в контроллере на UIView, он отлично работает. Но не с моим пользовательским представлением.

У кого-нибудь еще есть эта проблема? И это особенность, или просто мой идиотизм?

Код для контроллера

import UIKit

class ViewController: UIViewController {

    @IBOutlet var newView:MyView

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

Код для просмотра

import UIKit

class MyView: UIView {

    init(frame: CGRect) {
        super.init(frame: frame)
        // Initialization code
    }

    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect)
    {
        // Drawing code
    }
    */

}

person hobart    schedule 08.06.2014    source источник
comment
Я тоже столкнулся с этой проблемой, я думаю, что это ошибка, и вы должны сообщить об этом.   -  person Enrico Susatyo    schedule 08.06.2014


Ответы (3)


У меня была похожая проблема, и я думаю, что это частично проблема кэширования, а частично проблема Xcode6/Swift. Первый шаг, который я обнаружил, был необходим, чтобы убедиться, что файл .swift контроллера представления будет загружен в помощнике редактора при выборе «автоматического».

Когда Xcode обнаружил, что оба файла связаны, я иногда мог управлять перетаскиванием из представления/кнопки/и т. д. из IB в файл .swift, но часто приходилось перетаскивать из пустого круга в желобе строки @IBOutlet var newView:MyView в представление, которое я хотел, чтобы оно соответствовало.

Если вы не можете загрузить файл в помощнике редактора, я обнаружил, что часто работает следующее:

  1. Удалить пользовательский класс из представления IB
  2. Очистить проект (cmd+K)
  3. Закрыть/снова открыть Xcode
  4. Может, снова почистить?
  5. Добавьте пользовательский класс обратно в представление
  6. Надеюсь, что это работает :)

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

person Joseph Duffy    schedule 08.06.2014
comment
Спасибо. Ничто из этого на самом деле не решило прямую проблему (перетаскивание из существующего @IBOutlet в пользовательское представление в окне IB), но предоставило альтернативный подход - перетаскивание из окна MyView в окне IB в вспомогательный редактор, который создает (и ссылки) соответствующий IBOutlet. Кажется, это позволяет достичь той же общей потребности. - person hobart; 08.06.2014
comment
Зацеп из пустого круга в желобе сделал свое дело! Спасибо! - person jomafer; 28.09.2014

В моем случае import UIKit отсутствовал, после добавления этой строки я мог снова создать IBOutlet из раскадровки.

person gpichler    schedule 17.06.2015

У меня была похожая проблема, описанная в этой теме. Возможно, вы нашли решение, возможно, нет, но любой, кто столкнется с этим в будущем. Я обнаружил, что ключ заключается в использовании функции «требуемая инициализация» следующим образом:

required init(coder aDecoder: NSCoder) {
    print("DrawerView: required init")
    super.init(coder: aDecoder)!
    screenSize = UIScreen.mainScreen().bounds
    screenWidth = screenSize.width
    screenHeight = screenSize.height
    self.userInteractionEnabled = true
    addCustomGestureRecognizer()
}

Это полный класс моего пользовательского представления:

импортировать фонд импорта UIKit

класс DrawerView: UIView {

var screenSize: CGRect!
var screenWidth: CGFloat!
var screenHeight: CGFloat!

var drawerState: Int = 0

override init (frame : CGRect) {
    print("DrawerView: main init")
    super.init(frame : frame)
}

override func layoutSubviews() {
    print("DrawerView: layoutSubviews")
    super.layoutSubviews()
}

convenience init () {
    self.init(frame:CGRect.zero)
}

required init(coder aDecoder: NSCoder) {
    print("DrawerView: required init")
    super.init(coder: aDecoder)!
    screenSize = UIScreen.mainScreen().bounds
    screenWidth = screenSize.width
    screenHeight = screenSize.height
    self.userInteractionEnabled = true
    addCustomGestureRecognizer()
}

func addCustomGestureRecognizer (){
    print("DrawerView: addCustomGestureRecognizer")
    let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(self.handleDrawerSwipeGesture(_:)))
    swipeDown.direction = UISwipeGestureRecognizerDirection.Down
    self.addGestureRecognizer(swipeDown)
    let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(self.handleDrawerSwipeGesture(_:)))
    swipeUp.direction = UISwipeGestureRecognizerDirection.Up
    self.addGestureRecognizer(swipeUp)
    print("DrawerView self: \(self)")
}

func minimizeDrawer(){
    UIView.animateWithDuration(0.25, delay: 0.0, options: .CurveEaseOut, animations: {
        //            let height = self.bookButton.frame.size.height
        //            let newPosY = (self.screenHeight-64)*0.89
        //            print("newPosY: \(newPosY)")
        self.setY(self.screenHeight*0.86)
        }, completion: { finished in
            self.drawerState = 0
            for view in self.subviews {
                if let _ = view as? UIButton {
                    let currentButton = view as! UIButton
                    currentButton.highlighted = false
                } else if let _ = view as? UILabel {
                    let currentButton = view as! UILabel
                    if self.tag == 99 {
                        currentButton.text = "hisotry"
                    } else if self.tag == 999 {
                        currentButton.text = "results"
                    }
                }
            }
    })
}

func handleDrawerSwipeGesture(gesture: UIGestureRecognizer) {
    print("handleDrawerSwipeGesture: \(self.drawerState)")
    if let swipeGesture = gesture as? UISwipeGestureRecognizer {
        switch self.drawerState{
        case 0:
            if swipeGesture.direction == UISwipeGestureRecognizerDirection.Down {
                // nothing to be done, mini and swiping down
                print("mini: !")
            } else {
                // mini and swiping up, should go to underneath city box
                UIView.animateWithDuration(0.25, delay: 0.0, options: .CurveEaseOut, animations: {
                    let toYPos:CGFloat = 128 + 64 + 8
                    self.setY(toYPos)
                    }, completion: { finished in
                        self.drawerState = 1
                        for view in self.subviews {
                            if let _ = view as? UIButton {
                                let currentButton = view as! UIButton
                                currentButton.highlighted = true
                            } else if let _ = view as? UILabel {
                                let currentLabel = view as! UILabel
                                currentLabel.text = "close"
                            }
                        }

                })
            }
            break;
        case 1:
            if swipeGesture.direction == UISwipeGestureRecognizerDirection.Down {
                // open and swiping down
                self.minimizeDrawer()
            } else {
                // open and swiping up, nothing to be done
            }
            break;
        default:
            break;
        }
    }
}

}

Надеюсь это поможет...

person Giggs    schedule 19.05.2016