답변:
예. segue를 사용하여 하위 뷰 컨트롤러 (및 해당 뷰 및 하위 뷰)에 액세스 할 수 있습니다. alertview_embed
스토리 보드의 속성 관리자를 사용하여 segue에 식별자 (예 :)를 제공하십시오 . 그런 다음 부모보기 컨트롤러 (컨테이너보기를 수용하는 컨트롤러)에게 다음과 같은 방법을 구현하십시오.
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString * segueName = segue.identifier;
if ([segueName isEqualToString: @"alertview_embed"]) {
AlertViewController * childViewController = (AlertViewController *) [segue destinationViewController];
AlertView * alertView = childViewController.view;
// do something with the AlertView's subviews here...
}
}
당신은 단순히 다음과 같이 할 수 있습니다 self.childViewControllers.lastObject
(자녀가 하나 있다고 가정하면 그렇지 않으면 사용하십시오 objectAtIndex:
).
childViewControllers
"너무 빨리"에 액세스 한 이후로 충돌합니다.
스위프트 프로그래밍
이렇게 쓸 수 있습니다
var containerViewController: ExampleViewController?
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// you can set this name in 'segue.embed' in storyboard
if segue.identifier == "checkinPopupIdentifierInStoryBoard" {
let connectContainerViewController = segue.destinationViewController as ExampleViewController
containerViewController = connectContainerViewController
}
}
이 prepareForSegue
접근 방식은 작동하지만 segue 식별자 매직 문자열을 사용합니다. 더 좋은 방법이있을 수 있습니다.
VC의 클래스를 알고 있다면 계산 된 속성으로 매우 깔끔하게 수행 할 수 있습니다.
var camperVan: CamperVanViewController? {
return childViewControllers.flatMap({ $0 as? CamperVanViewController }).first
// This works because `flatMap` removes nils
}
에 의존합니다 childViewControllers
. 첫 번째 수업에 의존하는 것은 깨지기 쉬울 수 있지만 동의하는 수업의 이름을 지정하면 이것이 상당히 견고 해 보입니다.
return childViewControllers.filter { $0 is CamperVanViewController }.first
라이너 하나
childViewControllers.flatMap({ $0 as? CamperVanViewController }).first
그것이 조금 더 나은 것으로 생각합니다.
first(where:)
. childViewControllers.first(where: { $0 is CamperVanViewController })
뷰 컨트롤러의 유형에 Swift의 switch 문을 사용하는 다른 방법이 있습니다.
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
switch segue.destination
{
case let aViewController as AViewController:
self.aViewController = aViewController
case let bViewController as BViewController:
self.bViewController = bViewController
default:
return
}
}
경우에는 누군가가 찾고있는 스위프트 3.0 ,
그러면 viewController1 , viewController2 등에 액세스 할 수 있습니다.
let viewController1 : OneViewController!
let viewController2 : TwoViewController!
// Safety handling of optional String
if let identifier: String = segue.identifier {
switch identifier {
case "segueName1":
viewController1 = segue.destination as! OneViewController
break
case "segueName2":
viewController2 = segue.destination as! TwoViewController
break
// ... More cases can be inserted here ...
default:
// A new segue is added in the storyboard but not yet including in this switch
print("A case missing for segue identifier: \(identifier)")
break
}
} else {
// Either the segue or the identifier is inaccessible
print("WARNING: identifier in segue is not accessible")
}
일반적으로 몇 가지 달콤한 일을 할 수 있습니다. 다음은 Array의 확장입니다.
extension Array {
func firstMatchingType<Type>() -> Type? {
return first(where: { $0 is Type }) as? Type
}
}
그런 다음 viewController 에서이 작업을 수행 할 수 있습니다.
var viewControllerInContainer: YourViewControllerClass? {
return childViewControllers.firstMatchingType()!
}