2014-11-05 3 views
8

스토리 보드를 사용하는 Mac 문서 기반 코어 데이터 응용 프로그램이 있습니다. 스토리 보드의 레이아웃은 다음과 같습니다.다중 스토리 보드 장면에서 NSArrayController 사용

Window Controller 
    Split View Controller 
     Table View Controller 
     Text View Controller 

내 핵심 데이터 모델에는 제목과 내용의 두 가지 속성이 포함 된 장 엔터티가 있습니다. 테이블 뷰에서 각 장의 제목을 표시하고 싶습니다. 텍스트보기에는 선택한 장의 내용이 표시됩니다.

xib 파일을 사용 중이라면 어레이 컨트롤러를 xib 파일에 추가합니다. 내 NSPersistentDocument 하위 클래스에 액세스하려면 배열 컨트롤러를 File 's Owner에 바인딩합니다. 테이블 뷰를 배열 컨트롤러의 alignedObjects 속성에 바인드하고 배열 뷰어에 텍스트 뷰를 바인딩합니다.

하지만 스토리 보드에서는 상황이 더욱 복잡해집니다. 배열 컨트롤러를 테이블보기 컨트롤러에 추가하고 테이블보기를 배열 컨트롤러에 바인딩하고 장 제목을 테이블보기에 표시 할 수 있습니다. 그러나 어레이 컨트롤러가 다른 장면에 있기 때문에 텍스트보기 컨트롤러는 해당 어레이 컨트롤러에 바인딩 할 수 없습니다.

인터페이스 뷰어 컨트롤러와 텍스트보기 컨트롤러가 모두 인터페이스 컨트롤러에 추가하여 바인딩 할 수 있도록 인터페이스 컨트롤러에 배열 컨트롤러를 추가하려면 어떻게합니까?

+0

그냥 속성으로 응용 프로그램의 위임에 충실하지만 keypaths는 부모 뷰에 존재합니다

내가 여기이 설명하는 예제 프로젝트를 만든이 모두 명확를 만들려면 OSX 스토리 보드에서? – stevesliva

+1

NSViewController에는 parentViewController 속성이 있습니다. 그러나 배열 컨트롤러를 분할보기 컨트롤러에 추가하고 parentViewController.arrayController.arrangedObjects의 모델 키 경로를 사용하여 테이블보기 열의 값 바인딩을 테이블보기 컨트롤러에 바인딩하면 클래스가 KVC 호환이 아니라고 말하는 충돌이 발생합니다. 키 arrayController. 배열 컨트롤러의 콘센트를 분할보기 컨트롤러 하위 클래스에 추가하고 IB에서 만든 배열 컨트롤러에 콘센트를 연결했는데 같은 오류가 발생합니다. –

+0

나는 이것을 다시 읽고 있었다 ... 아마도 당신의 arrayController 속성을 가진 특정 서브 클래스를 반환하기 위해 parentViewController 게터를 오버라이드 했을까? 그것은 추한, 그래도. – stevesliva

답변

14

이 작업을 수행하는 데 핵심은 내림차순 NSViewController 하위 클래스 각각에 NSArrayController 인스턴스를 가지고 중앙 데이터 소스 (대개 NSDocument 하위 클래스)를 통해 바인딩하는 것입니다. 그런 다음이 데이터 소스를 내림차순 컨트롤러를 통과하여 NSViewController 하위 클래스 representedObject으로 설정할 수 있습니다.

class Document: NSDocument { 

    var dataSource: DataSource? = DataSource() 

    ... 
} 

class DataSource: NSObject, NSCoding { 

    var items: [Item] = [] 
    var selectionIndexes: NSIndexSet = NSIndexSet() 

    ... 
} 

class WindowController: NSWindowController { 

    override var document: AnyObject? { 
     didSet { 
      if let document = self.document as? Document { 
       self.contentViewController?.representedObject = document 
      } 
     } 
    } 

} 

class SplitViewController: NSSplitViewController { 

    override var representedObject: AnyObject? { 
     didSet { 
      for viewController in self.childViewControllers as! [NSViewController] { 
       viewController.representedObject = representedObject 
      } 
     } 
    } 
} 

트릭 각 행 representedObject 바인딩한다 : 여기서 두 개의 아이 뷰 컨트롤러 (마스터/세부 설정)와 NSSplitViewController 인 콘텐츠보기 컨트롤러 갖는 NSWindowController과 스토리 보드의 적용 예는 스토리 보드에서 내림차순보기 컨트롤러의 NSArrayController 중 하나입니다. 당신은 단지 contentArray이 아니라 selectionIndexes을 바인딩 할 필요가 있습니다.

그 결과 내림차순 NSArrayControllerselectionIndexes은 중앙 데이터 소스 (위의 예에서는 DataSource 하위 클래스)를 통해 바인딩되기 때문에 동기화 상태로 유지됩니다. (주로, 농담.) https://github.com/acwright/StoryboardBindingsExample

+0

인상적.나는 당신의 예를 다운로드했고, 그것은 효과가있다. 저는이 달 전에 대답 해주기를 바랍니다. 현재 프로젝트의 바인딩을 사용하지 않았지만 다시 전환하지는 않지만 스토리 보드를 사용하는 향후 프로젝트에서이 대답을 염두에 두겠습니다. –

+0

감사합니다. 나는 시작하고 있던 프로젝트의 바인딩을 포기하고 있었지만 해결책이 있어야만한다고 느꼈다. 그렇다면 선택 사항을 동기화 상태로 유지하는 것이 문제였습니다. :) –

+0

코어 데이터 작업이 있습니까? 나는 당신이 한 것과 비슷한 아이디어를 가지고 있었지만, 선택 인덱스를 얻을 수 있고 그것이 한 장면에서 업데이트되었다는 것을 증명할 때, 나는 항상 두 번째 장면에서 빈 어레이 컨트롤러로 끝납니다. – LighteningKid

관련 문제