xcode Swift、iboutlet 和自定义控件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24104690/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 05:02:13  来源:igfitidea点击:

Swift, iboutlet and custom controls

iosxcodeswiftiboutlet

提问by hobart

I may be doing something really stupid, but I don't seem to be able to use Interface Builder to connect IBOutlet variables to custom views, but only in Swift.

我可能在做一些非常愚蠢的事情,但我似乎无法使用 Interface Builder 将 IBOutlet 变量连接到自定义视图,而只能在 Swift 中使用。

I've created a class called MyView, which extends from UIView. In my controller, I've got a MyView variable (declared as @IBOutlet var newView: MyView). I go into IB and drag a UIView onto the window and give it a class of MyView.

我创建了一个名为 MyView 的类,它是从 UIView 扩展而来的。在我的控制器中,我有一个 MyView 变量(声明为 @IBOutlet var newView: MyView)。我进入 IB 并将一个 UIView 拖到窗口上并给它一个 MyView 类。

Whenever I've done similar in Objective C, I'm then able to click on the View Controller button at the top of the app window, select the variable and drag it down to the control to link the two together. When I try it in Swift, it refuses to recognise that the view is there.

每当我在 Objective C 中完成类似的操作时,我就可以单击应用程序窗口顶部的 View Controller 按钮,选择变量并将其向下拖动到控件以将两者链接在一起。当我在 Swift 中尝试它时,它拒绝承认视图在那里。

If I change the class of the variable in the controller to UIView, it works fine. But not with my custom view.

如果我将控制器中变量的类更改为 UIView,它就可以正常工作。但不是我的自定义视图。

Has anyone else got this problem? And is it a feature, or just my idiocy?

有没有其他人遇到过这个问题?这是一个功能,还是我的白痴?

Code for Controller

控制器代码

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.
    }
}

Code for view

查看代码

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
    }
    */

}

回答by Joseph Duffy

I've had a similar problem, and I think it's partially a caching issue and partially just an Xcode6/Swift issue. The first step I found was required was to make sure that the view controller .swift file would be loaded in the Assistant Editor when choosing "automatic".

我遇到了类似的问题,我认为它部分是缓存问题,部分只是 Xcode6/Swift 问题。我发现需要的第一步是确保在选择“自动”时将视图控制器 .swift 文件加载到助手编辑器中。

With Xcode finding that both the files are linked I could sometimes control-drag from the view/button/etc. from the IB to the .swift file, but often had to drag from the empty circle in the gutter of the @IBOutlet var newView:MyViewline to the view I wanted it to match up to.

随着 Xcode 发现这两个文件都已链接,我有时可以从视图/按钮/等控件拖动。从 IB 到 .swift 文件,但经常不得不从@IBOutlet var newView:MyView行的装订线中的空圆圈拖动到我希望它匹配的视图。

If you can't get the file to load in the Assistant Editor then I found that doing the following would often work:

如果您无法在助理编辑器中加载文件,那么我发现执行以下操作通常会奏效:

  1. Remove the custom class from the IB view
  2. Clean the project (cmd + K)
  3. Close/reopen Xcode
  4. Possibly clean again?
  5. Add the custom class back to the view
  6. Hope it works :)
  1. 从 IB 视图中删除自定义类
  2. 清理项目(cmd + K)
  3. 关闭/重新打开 Xcode
  4. 可能又干净了?
  5. 将自定义类添加回视图
  6. 希望它有效:)

If that seems to get you half way/nowhere add a comment and I'll see if it triggers anything else I did

如果这似乎让你中途/无处添加评论,我会看看它是否会触发我所做的其他任何事情

回答by gpichler

In my case import UIKitwas missing, after adding this line I could create an IBOutlet from Storyboard again.

在我的情况下import UIKit,在添加此行后,我可以再次从 Storyboard 创建一个 IBOutlet。

回答by Giggs

I've had a similar problem to the one described in this thread. Maybe you found a solution maybe not but anybody who encounters this in the future. I've found the key is to use the "required init" function as follows:

我遇到了与此线程中描述的问题类似的问题。也许您找到了解决方案,也许不是,但将来遇到此问题的任何人。我发现关键是使用“必需的初始化”功能,如下所示:

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()
}

This is the complete class of my custom view:

这是我的自定义视图的完整类:

import UIKit import Foundation

导入 UIKit 导入基础

class DrawerView: UIView {

类抽屉视图: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;
        }
    }
}

}

}

Hope this helps...

希望这可以帮助...