뷰 컨트롤러:프로그래밍 방식으로 뷰를 전환하는 방법은 무엇입니까?
-
06-09-2019 - |
문제
간단히 말해서:보기 A와 보기 B 사이를 전환할 수 있는 두 개의 전체 화면 보기를 갖고 싶습니다.탭 바 컨트롤러를 사용할 수 있다는 것을 알고 있지만 그러고 싶지는 않습니다.내부적으로 무슨 일이 일어나고 있는지 알아보기 위해 이것이 어떻게 수동으로 수행되는지 보고 싶습니다.
루트 컨트롤러 역할을 하는 UIViewController가 있습니다.
@interface MyRootController : UIViewController {
IBOutlet UIView *contentView;
}
@property(nonatomic, retain) UIView *contentView;
@end
contentView는 Nib의 "뷰"에 하위 뷰로 추가한 UIView에 연결됩니다.이것은 녹색이며 전체 화면으로 보입니다.잘 작동합니다.
그런 다음 거의 같은 방식으로 두 개의 다른 View Controller를 만들었습니다.ViewControllerA 및 ViewControllerB.ViewControllerA의 배경은 파란색이고, ViewControllerB의 배경은 검정색입니다.어느 것이 활성화되어 있는지 확인하십시오.
따라서 myRootController 구현에서는 다음을 수행합니다.
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
ViewControllerA *vcA = [[ViewControllerA alloc] initWithNib];
[self.contentView addSubview:vcA.view];
[cvA release];
}
그런데 -initWithNib 메소드는 다음과 같습니다.
- (id)initWithNib { // Load the view nib
if (self = [super initWithNibName:@"ViewA" bundle:nil]) {
// do ivar initialization here, if needed
}
return self;
}
작동합니다.앱을 시작할 때 ViewControllerA의 뷰가 표시됩니다.그러나 이제 가장 큰 질문은 다음과 같습니다.View Controller에는 일반적으로 다음과 같은 모든 메소드가 있습니다.
- (void)viewWillAppear:(BOOL)animated;
- (void)viewDidDisappear:(BOOL)animated;
- (void)viewDidLoad;
...등등.탭 막대 컨트롤러 없이 "내" 방식으로 수행하면 누구 또는 무엇, 또는 어떻게 해당 메서드가 호출됩니까?내 말은:ViewController의 클래스를 할당하고 뷰 가져오기가 표시되면 해당 메서드 호출에 주의해야 합니까?viewWillAppear, viewDidDisappear 또는 viewDidLoad를 어떻게 알 수 있나요?나는 탭 바 컨트롤러의 내부에 이 모든 "영리함"이 있다고 믿습니다.아니면 내가 틀렸나요?
업데이트:나는 그것을 테스트했습니다.뷰 컨트롤러를 해제하면(예:ViewControllerA), viewDidDisappear에 대한 로그 메시지가 표시되지 않습니다.ViewControllerA를 할당하고 초기화할 때만 viewDidLoad를 얻습니다.하지만 그게 다야.이제 모든 표시는 UITabBarController의 영리함을 나타냅니다. ;) 그리고 저는 그것을 복제하는 방법을 알아내야 합니다. 그렇죠?
해결책
가장 간단한 removefromsuperview/insertsubview에서 시작하여 코드를 조금씩 추가 할 수 있습니다.
//SwitchViewController.h
#import
@class BlueViewController;
@class YellowViewController;
@interface SwitchViewController : UIViewController {
IBOutlet BlueViewController *blueViewController;
IBOutlet YellowViewController *yellowViewController;
}
- (IBAction)switchViews:(id)sender;
@property (nonatomic, retain) BlueViewController *blueViewController;
@property (nonatomic, retain) YellowViewController *yellowViewController;
@end
//1. remove yellow view and insert blue view
- (IBAction)switchViews:(id)sender {
if(self.blueViewController.view.superview == nil)
{
[yellowViewController.view removeFromSuperview];
[self.view insertSubview:blueViewController.view atIndex:0];
}
}
//2. appear=insert, disappear=remove
if(blueViewController.view.superview == nil)
{
[blueViewController viewWillAppear:YES];
[yellowViewController viewWillDisappear:YES];
[yellowViewController.view removeFromSuperview];
[self.view insertSubview:self.blueViewController.view atIndex:0];
[yellowViewController viewDidDisappear:YES];
[blueViewController viewDidAppear:YES];
}
//3. now add animation
[UIView beginAnimations:@"View Flip" context:nil];
[UIView setAnimationDuration:1.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
//blue view will appear by flipping from right
if(blueViewController.view.superview == nil)
{
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight
forView:self.view cache:YES];
[blueViewController viewWillAppear:YES];
[yellowViewController viewWillDisappear:YES];
[yellowViewController.view removeFromSuperview];
[self.view insertSubview:self.blueViewController.view atIndex:0];
[yellowViewController viewDidDisappear:YES];
[blueViewController viewDidAppear:YES];
}
[UIView commitAnimations];
다른 팁
iPhone 개발 시작 6 장에서보기 전환의 좋은 예가 있습니다. 여기에서 소스 코드를 볼 수 있습니다.http://iphonedevbook.com/
SwitchViewController에는 뷰를 프로그래밍 방식으로 변경하는 코드가 있습니다.
- (IBAction)switchViews:(id)sender
{
if (self.yellowViewController == nil)
{
YellowViewController *yellowController = [[YellowViewController alloc]
initWithNibName:@"YellowView" bundle:nil];
self.yellowViewController = yellowController;
[yellowController release];
}
[UIView beginAnimations:@"View Flip" context:nil];
[UIView setAnimationDuration:1.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
UIViewController *coming = nil;
UIViewController *going = nil;
UIViewAnimationTransition transition;
if (self.blueViewController.view.superview == nil)
{
coming = blueViewController;
going = yellowViewController;
transition = UIViewAnimationTransitionFlipFromLeft;
}
else
{
coming = yellowViewController;
going = blueViewController;
transition = UIViewAnimationTransitionFlipFromRight;
}
[UIView setAnimationTransition: transition forView:self.view cache:YES];
[coming viewWillAppear:YES];
[going viewWillDisappear:YES];
[going.view removeFromSuperview];
[self.view insertSubview: coming.view atIndex:0];
[going viewDidDisappear:YES];
[coming viewDidAppear:YES];
[UIView commitAnimations];
}
내가 올바르게 이해한다면, 당신이 성취하려는 것은 매우 간단합니다.
응용 프로그램 대의원에 UinavationController를 추가하고 다음과 같이하십시오.
[navigationController pushView:vcA];
대의원은 그에 따라 부름을받습니다.
- (void) ViewWillAppear : (bool) 애니메이션;
- (void) ViewDidDisAppear : (bool) 애니메이션;
- (void) ViewDidload;
그리고 당신이보기를 터뜨리고 다른보기를 밀고 싶을 때 :
[navigationController popViewControllerAnimated:true];
[navigationController pushView:vcB];
NavigationController가 사용하는 것을 원하지 않으면 사용 만 표시하십시오.
[navigationBar setHidden:YES];
여기서 NavigationBar는 UinaVigationController에 해당하는 UinaVigationBar입니다.
이것은 오래된 문제일지도 모르지만 최근에 같은 문제가 발생하여 작동하는 것을 찾는 데 어려움을 겪었습니다.나는 두 개의 보완적인 뷰 컨트롤러 사이를 전환하고 싶었지만 스위치가 애니메이션화되기를 원했고(내장된 애니메이션은 잘 작동함) 가능하다면 스토리보드와 호환되기를 원했습니다.
내장된 전환 기능을 활용하기 위해 UIView의 +transitionFromView:toView:duration:options:completion:
방법은 아름답게 작동합니다.그러나 뷰 컨트롤러가 아닌 뷰 사이에서만 전환됩니다.
뷰뿐만 아니라 전체 뷰 컨트롤러 간에 전환이 이루어지도록 하려면 사용자 정의를 생성합니다. UIStoryboardSegue
가는 길입니다.스토리보드 사용 여부에 관계없이 이 접근 방식을 사용하면 전체 전환을 캡슐화하고 한 뷰 컨트롤러에서 다음 뷰 컨트롤러로 관련 정보 전달을 관리할 수 있습니다.서브클래싱만 포함됩니다. UIStoryboardSegue
단일 메서드를 재정의하고, -perform
.
참조 구현은 다음을 참조하세요. RAFlipReplaceSegue
, 이 접근 방식을 사용하여 구성한 정확한 사용자 정의 segue입니다.보너스로, 이전 뷰 컨트롤러가 새로운 뷰 컨트롤러로 대체됩니다. UINavigationController
스택.