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


102

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!

감사합니다.


변경하지 않겠습니까! 에?

clearView는 스토리 보드에 연결되지 않았기 때문에 nil입니다 (연결되지 않았 음을 나타내는 구멍이있는 코드 왼쪽의 원 참조). 스크린 샷에서 annotationOptionView의 선언을 볼 수 없습니다.
Javier Flores Font

@JavierFloresFont : clearView전 전무가 될 것으로 예상합니다. 아직 리팩터링하지 않은 것입니다. 그림 A의 각주도 참조하십시오. @ShaanSingh 그래야합니다! 스토리 보드로부터의 연결은 런타임에 설정되며 nil이 아니어야하기 때문입니다.
Stefan Arambasich

이 뷰 컨트롤러는 어떻게로드됩니까? 요청하는 코드를 보여 주거나 연결되는 segue를 설명하세요.
rob mayoff

1
올바른 스토리 보드를 얻고 있습니다. let vc = UIStoryboard(name: "LocationPickerModal", bundle: nil) .instantiateViewControllerWithIdentifier("LocationPickerModalViewController") as LocationPickerModalViewController
Stefan Arambasich

답변:


146

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

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

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


4
이것은 viewWillAppear:호출 되었을 때 발생 합니다. 처음으로 그 콘센트로 무엇이든 할 때 입니다. 보기에 액세스해도 나에게 아무런 영향이 없습니다. 아직 없습니다.
Stefan Arambasich 2015 년

감사! 이것은 나에게도 효과적이었습니다. var v = viewcontroller.view; 뷰 계층 구조를 강제로로드합니다. 멋진 트릭! ;)
Yordi Uytersprot 2015-08-27

@YordiUytersprot이 줄을 어디에 넣을까요?
Async- 2015

4
글쎄, 만약 당신이 viewcontroller를 인스턴스화한다면 : let vc = self.storyboard? .instantianteViewControllerWithIdentifier ( "StoryboardIDfromVC") as? CustomVC; let view = vc.view; // 지금은 CustomVC에서 IBOutlets에 액세스 할 수 있습니다 .. vc.customTextField.text = "Lalala"; 도움이 되었기를 바랍니다. :)
Yordi Uytersprot 2015

4
UIViewcontroller.loadViewIfNeeded()여기서 사용하기에 적합한 방법입니다.
orkoden 19-06-05

27

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


내가했다. 죄송합니다. 제 답변을 표시하려고 했어요. DerivedData프로젝트 의 폴더를 삭제 한 후에 만 ​​작동하기 시작했습니다 .
Stefan Arambasich 2015

3
내 뷰 계층 구조의 중간에있는 두 개의 아웃렛 만 nil이었습니다. 제품-> Clean이 저에게 효과적이었습니다!
Rikco

1
obj c, 그냥 프로젝트를 청소하는 것이 저에게 효과적이었습니다 ... 한 시간 이상을 보냈고 프로젝트를 청소할 생각조차하지 않았습니다. /하지만 감사합니다 !!
온실

Just Product-> Clean이 작동하지 않았지만 다른 시뮬레이터를 시작했고 작동 했으므로 DerivedData 폴더에도 문제가있을 것입니다.
endavid dec.

22

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

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


2
나는 UIStoryboard인스턴스를 만들고 instantiateViewControllerWithIdentifier그것을 호출 하고 있습니다.
Stefan Arambasich

15

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


2
이것이 답입니다. 나는 빌드 폴더와 모든 것을 청소하면서 꽤 오랫동안 이것을 싸웠습니다. 제 경우에는 viewDidLoad()모든 연결이 이루어졌지만 viewWillAppear()거의 모두 연결 되었습니다 nil(때로는 하나 또는 둘이 여전히 연결되어 있음). 나는 모든 것을 시도하고 마침내 파생 데이터 폴더를 삭제하고 다시 작성했으며 모든 것이 잘되었습니다.
ruttopia

6
3 년이 지난 후에도 Xcode 9.2에는 여전히 똑같은 버그가 있습니다. 정말 고맙습니다.
Kemal Can Kaynak

1
이것이 Xcode 11에 여전히 존재한다고보고합니다. :(
지출 됨

13

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


당신이 옳습니다. Swift Programming Language로 된 ARC 계수 콘텐츠를 자세히 읽었습니다. IBOutlet 약한 속성이 여전히 nil 인 이유를 찾을 수 없습니다. 마침내 '@IBOutlet swift nil'을 검색하고 SO에서 답변을 찾습니다. 그런 다음 Xcode 템플릿이 viewDidLoad에 'self.collectionView! .registerClass'를 추가 한 줄을 표시했습니다. 그런 다음 작동합니다. 당신은 내 생명을 구합니다.
charles.cc.hsu

12

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


XIB 파일을 사용하는 경우 직접 인스턴스화는 여전히 성공적으로 작동합니다.
Luat Vu Dinh

11

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

-(void)loadView {
// blank
}

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

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

아니면 그냥 전화

[super loadView];

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


8

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

7

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

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

직접 대신

let initialVC = InitialVC()

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


6

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

class XYZViewController: UINavigationController {
}

(즉, UINavigationController아님으로 UIViewController).

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

선언을 다음으로 변경

class XYZViewController: UIViewController {
}

완전히 고쳤습니다.


5

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

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

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


즉, 문제가 아니었다
스테판 Arambasich

4

2019 년,이 끔찍한 문제에 대한 한 가지 가능성 :

  • 일종의 시계를 보여주는 컨테이너보기가 있다고 가정 해 보겠습니다. 그래서 당신은

    클래스 Clock : UIViewController

실제로 앱의 여러 위치에서 사용합니다. .

메인 화면, 상세 화면, 편집 화면.

복잡한 snapchat과 같은 최신 앱이 있습니다.

사실, Clock실제로로드 할 수 번 이상 상기 동시에 온 곳 같은 화면 . (어떤 경우에는 숨겨져있을 수 있습니다.)

Clock여러 스토리 보드 중 하나 에서의 한 인스턴스에서 작업을 시작 합니다.

해당 스토리 보드에 NewLabel이라는 레이블을 추가합니다.

당연히 코드에 콘센트를 추가합니다. 모든 것이 작동합니다. 다른 모든 콘센트는 완벽하게 작동합니다.

당신은 확실히 콘센트를 연결.

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

Xcode는 "콘센트를 연결하는 것을 잊었습니다"라고 명확하게 알려줍니다.

그 이유는 .......... 시계의 스토리 보드 사용 중 하나 에 만 "NewLabel"이 있습니다 !

충돌은 실제로 >>> 다른 곳에서 <<<< 시계를 사용하고 있습니다 !!!!

Xcode 충돌이 작업중인 곳이 아닌 다른 곳 에서 발생했다고 알려주지 않습니다 .

충돌은 실제로 작업중인 곳에서 발생하는 것이 아닙니다 . 해당 스토리 보드에 "NewLabel"항목이없는 다른 스토리 보드에서 발생했습니다 !!!

실망 스럽네요.


3

Swift 3의 경우

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

2

스토리 보드에서 콘센트를 인스턴스화하려면 먼저 뷰 계층 구조를로드해야합니다. 이를 위해 loadView 또는 loadViewIfNeeded 메서드를 수동으로 호출 할 수 있습니다.


2

제 경우에는 앱이 갑자기 충돌하기 시작했습니다. 이 모든 콘센트는 여전히 동일한 것으로 확인 디버깅 nilviewDidLoad().

내 앱은 여전히 대부분의 뷰 컨트롤러에 대해 (스토리 보드가 아닌) 펜촉을 사용합니다 . 모든 것이 제자리에 있었고 모든 콘센트가 올바르게 연결되었습니다. 다시 확인했습니다.

일반적으로 뷰 컨트롤러를 다음과 같이 인스턴스화합니다.

let newVC = MYCustomViewController()

... 어떤 이유로 오랫동안 .xib이 확실하지 어떻게 작업 (뷰 컨트롤러 클래스와 같은 이름대로로 작동하는 것 같다 우리는있다.하지만 하지 호출 init(nibName:bundle:)전무 인수, 또는 재정 init()에 그렇게 self맘 일반적으로 제안됩니다 ...).

그래서 명시 적으로

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

... 런타임 예외 오류 만 표시됩니다.

*** 포착되지 않은 예외 'NSInternalInconsistencyException'으로 인해 앱 종료, 이유 : '번들에 NIB를로드 할 수 없음 :'NSBundle </ Users / nicolasmiari / Library / Developer / CoreSimulator / Devices / 3DA3CF21-108D-498F-9649-C4FC9E3C1A8D / data /Containers/Bundle/Application/C543DDC1-AE86-4D29-988C-9CCE89E23543/MyApp.app> (loaded) '이름이'MYCustomViewController '인

그리고 그때 , 나는 그것을 보았다 :

.xib 파일의 "Target Membership"확인란이 선택 취소되었습니다.


Xcode 프로젝트 파일과 관련하여 자주 발생하는 병합 충돌 중 하나를 해결할 때 발생했을 것입니다.

Apple은 확실히 SCM에 더 친숙한 프로젝트 파일 형식을 제시해야합니다.


2

StoryBoard없이 XIB에서 ViewController를 생성하기위한 100 % 작동 솔루션

  1. CustomViewController 클래스 생성 : UIViewController
  2. CustomViewControllerView.xib보기 만들기
  3. Interface Builder의 CustomViewControllerView.xib에서 Placeholders-> File 's Owner를 선택하십시오.
  4. "속성 관리자"에서 클래스를 CustomViewController로 설정합니다.
  5. "Connections inspector"에서 "view"를 xib의 최상위보기에 연결합니다 (최상위보기의 클래스가 CustomViewController를 가리키고 있지 않은지 확인)
  6. "연결 검사기"에서 다른 콘센트를 연결합니다 (필요한 경우 / 존재하는 경우).
  7. 상위 뷰 컨트롤러 / 앱 델리게이트에 CustomViewController 인스턴스 생성

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")

환상적인 대답, 감사합니다! 그 가치 를 위해 CustomViewController 클래스에서 직접 init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?)7.2 단계를 재정의 하고 호출 할 수도 있습니다 self.
brandonscript 2019-02-12

1

파일 소유자 또는보기에 연결된 경우 IBOutlet 연결을 확인하십시오. 실수가있을 수 있습니다.


1

다른 경우 :

아웃렛은 뷰 컨트롤러의 뷰가 실제로 인스턴스화 될 때까지 설정되지 않습니다. 귀하의 경우에는 아마도 initWithNibName : bundle :-어느 시점에서 여전히 nil이 될 것입니다. 이러한 콘센트와 관련된 모든 설정은 뷰 컨트롤러의 -viewDidLoad 메소드에서 발생해야합니다.


1

저에게는 현지화 된 스토리 보드에서 동일한 오류가 발생했습니다. 요소가 다른 로케일이 아닌 일부 로케일에 추가 되었기 때문에 누락 된 요소 로케일로 전환 할 때 해당 요소에 대해 null 참조가 있었기 때문에 (중복) 현지화를 제거해야했습니다. https://stackoverflow.com/a/42256341/1356559를 사용하는 스토리 보드 .


1

나를 위해 이것은 containerView0 이기 때문에 충돌했습니다 .

다음은 Crash 사용하는 코드입니다 .

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

누락 된 것은 super.loadView(). 그래서 그것을 추가하면 문제가 해결되었습니다.

고정 코드 :

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

loadView ()를 직접 호출해서는 안됩니다 ( developer.apple.com/documentation/uikit/uiviewcontroller/… ), 대신 self.view를 호출하십시오
Lio

1

스토리 보드에서 이미 식별자를 정의한 후 사용자 지정 셀에 대해 이전에 register (_ : forCellReuseIdentifier :)를 추가했을 때 비슷한 문제가 발생했습니다. viewDidLoad () 함수에이 코드가 있습니다. 일단 제거하면 잘 작동했습니다.


1

내가 방금 만난 또 다른 사건. UIViewController의 클래스 이름을 변경했지만 인터페이스가 빌드 된 .xib 파일의 이름을 변경하는 것을 잊었습니다.

이것을 포착하고 파일 이름에 클래스 이름을 반영하면 모든 것이 좋았습니다!

누군가에게 도움이되기를 바랍니다.


1

하나 더 있어요 ...

UITableViewCell에 대한 사용자 정의 클래스가 있지만 셀 스타일에서 Custom을 지정하는 것을 잊은 경우.


1

is보기가로드되었는지 확인할 수 있습니다.

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

0
  1. 둘 다 선택 .h하고 .m컨트롤러 파일보기
  2. 해당 파일의 참조 제거
  3. 프로젝트 트리에 파일을 다시 추가하십시오.
  4. 스토리 보드를 열고 결국 프로젝트를 다시 빌드하십시오.

0

실수로 내 뷰 컨트롤러 AVPlayerViewControllerUIViewController. 로 재생하여 UIViewController일 정상 백업합니다. 이것은 도움이 될 것입니다.

빌드 정리 (일반 및 전체), 파생 데이터 폴더 제거 및 Xcode 종료가 저에게 효과적이었습니다.


0

다른 viewcontroller 클래스 (스토리 보드에 링크 됨)와 함께 재사용하기 위해 클래스 (xib에 링크 됨)를 복사 한 후에도 동일한 문제가 발생했습니다. 제거하는 것을 잊었습니다

override var nibName

override var nibBundle

행동 양식.

그것들을 제거한 후 콘센트가 작동하기 시작했습니다.


0

나는 당신이 사용하는 것을 본다 ViewController!? 에 ViewController클래스 당신이 해야 사용 -viewDidLoad, 하지 -awakeFromNib , -awakeFromNib사용 UIView클래스



0

두 개가 main.storyboards있고 잘못된 것을 변경하는 경우 이런 일이 발생할 수 있습니다. 이는 인스턴스화되지 않은 콘센트에 연결할 때마다 발생할 수 있습니다 storyboard.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.