IT story

IBOutlet이 nil이지만 스토리 보드 인 Swift에 연결되어 있습니다.

hot-time 2020. 8. 27. 08:21
반응형

IBOutlet이 nil이지만 스토리 보드 인 Swift에 연결되어 있습니다.


Swift 1.1 및 Xcode 6.2 사용.

단일 사용자 지정 UIViewController하위 클래스가 포함 된 UIStoryboard가 있습니다. 여기에 해당 컨트롤러 에서 스토리 보드 하위 클래스@IBOutlet연결되는 유형이 UIView있습니다 . 또한 해당 뷰의 하위 뷰에 대한 유사한 콘센트가 있습니다. 그림 A를 참조하십시오.UIView

그러나 런타임에는 이러한 속성이 없습니다 (그림 B). 나는 Interface Builder에서 콘센트를 연결했다고 확신했지만.

생각 :

  • 하위 클래스의 하위 클래스를 사용하고 있기 때문에 초기화가 엉망이 될 수 있습니까? 이니셜 라이저를 재정의하지 않습니다.
  • awakeFromNib: 어떤 이유로 전화를받지 않습니다
  • 아마도 하위보기의 하위보기에 연결되지 않을 수 있습니다.

내가 시도한 것 :

  • @IBOutlet정확히 일치 및 스토리 보드 항목 유형 (대신 UIView)
  • 속성 및 콘센트를 삭제하고 다시 추가했습니다.

그림 A

그림 A *

그림 B

그림 B

* 가려진 코드 Figure A는 다음과 같습니다.

@IBOutlet private var annotationOptionsView: UIView!
@IBOutlet private var arrivingLeavingSwitch: UISegmentedControl!

감사합니다.


일반적으로 이것은 뷰 컨트롤러가 아직 뷰 계층 구조를로드하지 않았기 때문에 발생합니다. 뷰 컨트롤러는 view메시지를 보낼 때만 뷰 계층을로드 합니다. 실제로 같은 것들 후 발생하는 화면에 뷰 계층을 넣어 시간 때 시스템은이 작업을 수행 prepareForSegue:sender:하고 viewWillAppear:돌아왔다가.

VC가 아직 뷰 계층 구조를로드하지 않았기 때문에 아울렛은 여전히 ​​nil입니다.

을 말하여 VC가 뷰 계층 구조를로드하도록 할 수 _ = self.view있습니다.


제품> 청소를 실행 해 보셨습니까? 저에게 매우 유사한 문제를 해결했습니다.


Storyboard 또는 NIB에서 뷰 컨트롤러를 인스턴스화 했습니까? 아니면 이니셜 라이저를 통해 직접 인스턴스화 했습니까?

이니셜 라이저를 사용하여 클래스를 직접 인스턴스화하면 콘센트가 연결되지 않습니다. Interface Builder는 클래스의 사용자 정의 인스턴스를 생성하고 반복 디코딩을 위해 해당 인스턴스를 NIB 및 스토리 보드로 인코딩합니다. 클래스 자체를 정의하지는 않습니다. 이것이 문제라면 컨트롤러를 만드는 코드를 변경하여 UIStoryboard 또는 UINib의 메서드를 대신 사용하면됩니다.


스토리 보드는 내가 추가 한 추가 UI를 인식하지 못했습니다. 런타임에 모든 참조는 nil이었습니다. 그래서 파생 데이터 폴더를 지운 다음 해당 연결이 다시 작동했습니다.


이것은 내 사용자 지정 컬렉션 뷰 셀에서 나에게 발생했습니다. registerClassforReuseIdentifier 메서드를 registerNib로 바꿔야했습니다. 그것은 나를 위해 그것을 고쳤습니다.


제 경우에는 loadViewViewController 하위 클래스 메서드를 재정의 했지만 추가하는 것을 잊었 기 때문에 발생했습니다.[super loadView]

-(void)loadView {
// blank
}

loadView메서드 를 재정의 할 때 하위보기를 초기화하는 것은 사용자의 책임입니다. 이를 재정의하기 때문에 인터페이스 빌더의 뷰는 코코아 개체로 변환 할 기회를 얻지 못하므로 콘센트가 nil로 유지됩니다.

뷰 컨트롤러 하위 클래스에서 loadView를 구현하면 스토리 보드 / xib에서 코드로 UI 요소를로드하는 것이 사용자의 책임이됩니다.

아니면 그냥 전화

[super loadView];

그래서 슈퍼 클래스가 스토리 보드 / xib를 코드에로드 할 기회를 얻습니다.


controller.viewIBOutlets를 초기화하기 위해 뷰를 강제로로드하도록 호출 한 다음 값을 할당 할 수 있습니다.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if (segue.identifier == "identifier") {
        let controller = segue.destinationViewController as! YourController
        let _ = controller.view //force to load the view to initialize the IBOutlets

        controller.your_IBOutlet_property = xxx
        ...
        controller.delegate = self
    }
}

이것은 스토리 보드를 통해 인스턴스화하는 대신 실수로 뷰 컨트롤러를 직접 인스턴스화했기 때문에 발생했습니다. 직접 인스턴스화 MyViewController()하면 콘센트가 연결되지 않습니다.


나를 위해 이것은 실수로 뷰 컨트롤러의 클래스를 다음과 같이 선언했을 때 발생했습니다.

class XYZViewController: UINavigationController {
}

(즉, UINavigationController아님으로 UIViewController).

엑스 코드는 클래스가 빌드 좋은 것 같다,이 실수에 데리러와 같은 재정의 기능을하지 않는 viewDidLoad, viewWillAppear등 모든 작업을 올바르게. 그러나 그들 중 어느 것도 IBOutlet연결 되지 않습니다 .

선언을 다음으로 변경

class XYZViewController: UIViewController {
}

완전히 고쳤습니다.


최근에이 문제가 발생했습니다! 여기 내 생각이 있습니다. 문제는 스토리 보드 나 링크 문제가 아닙니다. ViewController를 시작하는 방법에 관한 것입니다. 특히 Swift를 사용하는 경우 (클래스 파일을 만들 때 편집기에 거의 아무것도 없습니다)

단순히 init()슈퍼 클래스에서 사용하면 스토리 보드로 작업 한 내용을 시작할 수 없습니다. 따라서해야 할 일은 ViewController의 초기화를 변경하는 것입니다. Replace let XXViewController = XXViewController()by let XXViewController = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("XXViewController") as! XXViewController이것은 프로그램이 스토리 보드로 이동하여 XXViewController를 찾아 IBOutlet스토리 보드에서 모두 시작하도록합니다 .

이 도움이 되길 바랍니다 ~ GL


view controller프로그래밍 방식으로 인스턴스화 하는 경우 . 그런 다음 아래와 같이 만들어보십시오.

let initialVC = self.storyboard?.instantiateViewController(withIdentifier: "InitialVC") as! InitialVC

직접 대신

let initialVC = InitialVC()

이것은 나를 위해 일했습니다.


Swift 3의 경우

func configureView() {
    let _  = self.view
}

You need to load the view hierarchy first in order to instantiate the outlets in the storyboard. For this, you can manually call the loadView or loadViewIfNeeded methods.


In my case, the app started crashing all of a sudden. Debugging it revealed that all outlets were still nil at the time of viewDidLoad().

My app still uses nibs (not storyboards) for most view controllers. Everything was in place, all outlets wired properly. I double-checked.

We typically instantiate our view controllers as

let newVC = MYCustomViewController()

...which for some reason seems to work as long as the .xib is named the same as the view controller class (not sure how that works, though. We are not calling init(nibName:bundle:) with nil arguments, or overriding init() to do so on self like it is typically suggested...).

So I tried to explicitly call

 let newVC = MYCustomViewController(nibName: "MYCustomViewController", bundle: .main)

...only to be greeted with the runtime exception error:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/nicolasmiari/Library/Developer/CoreSimulator/Devices/3DA3CF21-108D-498F-9649-C4FC9E3C1A8D/data/Containers/Bundle/Application/C543DDC1-AE86-4D29-988C-9CCE89E23543/MyApp.app> (loaded)' with name 'MYCustomViewController''

And then, I saw it:

The "Target Membership" checkbox of the .xib file was unchecked.


Must have happened when resolving one of the frequent merge conflicts regarding the Xcode project file.

Apple definitely needs to come up with a project file format that is more SCM-friendly.


100% Working solution for creating ViewControllers from XIB without StoryBoards

  1. Create class CustomViewController : UIViewController
  2. Create view CustomViewControllerView.xib
  3. In CustomViewControllerView.xib in Interface Builder select Placeholders -> File's Owner
  4. In "Attributes inspector" set Class to CustomViewController
  5. In "Connections inspector" connect "view" to top-level view of xib (ensure top-level view's Class is not pointing to CustomViewController)
  6. In "Connections inspector" connect other outlets (if needed/exist)
  7. Create an instance of CustomViewController in parent view controller/App delegate

7.1.

// creating instance
let controller = CustomViewController()

7.2.

// connecting view/xib with controller instance
let bundle = Bundle(for: type(of: controller))
bundle.loadNibNamed("CustomViewControllerView", owner: controller, options: nil)

7.3.

// get/set outlets
controller.labelOutlet.text = "title"
controller.imageOutlet.image = UIImage(named: "image1")

Check your IBOutlet connection if it connected to the File owner or the view. There could be mistakes.


Other case:

Your outlets won't get set until the view controller's view is actually instantiated, which in your case is probably happening shortly after initWithNibName:bundle:—at which point they'll still be nil. Any setup you do that involves those outlets should be happening in your view controller's -viewDidLoad method.


For me, I had same error on a localized storyboard, an element was added in some locale and not in the other, so I had null reference for that element when switched to the missing element locale, I had to remove (redundant) localization for that storyboard using https://stackoverflow.com/a/42256341/1356559.


For me, this was crashing because containerView was nil.

Here is my code with Crash.

@IBOutlet private var containerView: UIView!  // Connected to Storyboard
override open func loadView() {
    containerView.addSubview(anotherView)
}

The missing thing was calling the super.loadView(). So adding it solved problem for me.

Fixed Code:

@IBOutlet private var containerView: UIView!
override open func loadView() {
    super.loadView()
    containerView.addSubview(anotherView)
}

I had a similar issue when I had previously added register(_:forCellReuseIdentifier:) for the custom cell after I had already defined the identifier in the storyboard. Had this code in the viewDidLoad() function. Once I removed it, it worked fine.


Yet another case I just ran into. I changed the name of my class for the UIViewController, but I forgot to change the name of the .xib file where the interface was built.

Once I caught this and made the file names reflect the class name, it was all good!

I hope that helps someone.


Got one more ...

If you have a custom class for a UITableViewCell but forget to specify Custom in the Style of the cell.


You can validate if the is view is loaded.

if isViewLoaded && view.window != nil {
 //self.annotationOptionsView.
}

  1. select both .h and .m view controller files
  2. remove the reference of those files
  3. re-add the files to your project tree
  4. open the storyboard, eventually re-build the project

Accidently I subclassed my view controller with AVPlayerViewController instead of UIViewController. By replaying it to UIViewController things back normal. This should help.

No build cleaning (normal&full), removing derived data folders and quitting Xcode worked for me.


I had the same problem after copying a class (linked to a xib) to reuse it with another viewcontroller class (linked to a storyboard). I forgot to remove

override var nibName

and

override var nibBundle

methods.

After removing them, my outlets started to work.


I see you use ViewController!? in ViewController class you must use -viewDidLoad, not -awakeFromNib, -awakeFromNib use for UIView class


Check to see if you have any missing or disconnected outlets.

여기에 이미지 설명 입력


If you have two main.storyboards and you are making changes to the wrong one this can happen. This can happen anytime you connect an outlet from an uninstantiated storyboard.


2019, ONE POSSIBILITY FOR THIS HORRIBLE PROBLEM:

  • Say you have, perhaps, a container view that shows a, let's say, some sort of clock. So you have

    class Clock: UIViewController

You actually use it in a number of places in the app. On the main screen, the details screen and the edit screen.

You have a complicated snapchat-like modern app, and indeed, Clock may actually be loaded more than once at the same time (perhaps hidden).

Clock많은 스토리 보드 중 하나 에서의 한 가지 사용법에 대해 작업하기 시작 합니다. 새 레이블 L을 추가하고 물론 콘센트를 추가하면 작동합니다. 다른 모든 콘센트는 완벽하게 작동합니다.

그러나 앱은 L과 함께 nil로 충돌합니다.

그 이유는 .. 스토리 보드의 Clock 사용 중 하나에 "L"만 있기 때문입니다!

충돌은 실제로 >>> 다른 곳에서 <<< 시계를 사용하고 있습니다. (스토리 보드에 새로운 "L"항목이없는 경우).

실망 스럽네요.

참고 URL : https://stackoverflow.com/questions/29321383/iboutlet-is-nil-but-it-is-connected-in-storyboard-swift

반응형