탐색 컨트롤러 스택, 하위 뷰 또는 모달 컨트롤러를 사용하지 않고도 컨트롤러를 신속하게 변경할 수 있습니까?
NavigationController에는 관리할 ViewController 스택이 있으며 애니메이션 전환은 제한되어 있습니다.
기존 뷰 컨트롤러에 뷰 컨트롤러를 서브뷰 컨트롤러로 추가하려면 이벤트를 서브뷰 컨트롤러에 전달해야 하는데, 이는 관리하기가 번거롭고 귀찮은 요소가 거의 없으며 일반적으로 구현 시 불량 해킹처럼 느껴집니다(Apple도 이 작업에 반대합니다).
모달 뷰 컨트롤러를 다시 표시하면 뷰 컨트롤러가 다른 뷰 컨트롤러 위에 배치되며, 위에서 설명한 이벤트 전달 문제는 없지만 뷰 컨트롤러를 실제로 '바꾸지' 않고 스택합니다.
스토리보드는 iOS 5로 제한되어 있으며 거의 이상적이지만 모든 프로젝트에서 사용할 수는 없습니다.
위의 제한 없이 뷰 컨트롤러를 변경하고 그들 간의 애니메이션 전환을 허용하는 방법에 대해 솔리드 코드 예제를 제시할 수 있는 사람이 있습니까?
가까운 예이지만 애니메이션은 없습니다.탐색 컨트롤러 없이 여러 iOS 사용자 정의 보기 컨트롤러를 사용하는 방법
편집: Nav 컨트롤러를 사용하는 것은 괜찮지만 애니메이션 전환 스타일이 있어야 합니다(슬라이드 효과뿐만 아니라). 표시되는 뷰 컨트롤러를 스택이 아닌 완전히 교체해야 합니다.두 번째 뷰 컨트롤러가 스택에서 다른 뷰 컨트롤러를 제거해야 하는 경우에는 충분히 캡슐화되지 않은 것입니다.
편집 2: iOS 4가 이 질문의 기본 OS여야 합니다. 스토리보드를 언급할 때(위) 명확히 했어야 했습니다.
편집: 모든 방향에서 작동하는 새로운 답변입니다.원래 답변은 인터페이스가 세로 방향일 때만 작동합니다.이는 뷰를 대체하는 b/c 뷰 전환 애니메이션으로, 창에 추가된 첫 번째 뷰보다 적어도 한 단계 아래의 뷰를 사용해야 합니다(예:window.rootViewController.view.anotherView).
저는제부르간는단컨한테너클다구니습현했래를스이가▁i라는 간단한 컨테이너 클래스를 구현했습니다.TransitionController그것은 https://gist.github.com/1394947 에서 찾을 수 있습니다.
별도로, 저는 재사용이 더 쉬운 별도의 클래스 b/c에서 구현하는 것을 선호합니다.만약 당신이 그것을 원하지 않는다면, 당신은 단지 당신의 앱 대리인에게 동일한 논리를 직접 구현할 수 있습니다. 그래서 당신은 그것을 필요로 하지 않습니다.TransitionController하지만 여러분이 필요로 하는 논리는 같습니다.
다음과 같이 사용합니다.
앱 대리인에서
// add a property for the TransitionController
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
MyViewController *vc = [[MyViewContoller alloc] init...];
self.transitionController = [[TransitionController alloc] initWithViewController:vc];
self.window.rootViewController = self.transitionController;
[self.window makeKeyAndVisible];
return YES;
}
보기 컨트롤러에서 새 보기 컨트롤러로 전환하려면 다음과 같이 하십시오.
- (IBAction)flipToView
{
anotherViewController *vc = [[AnotherViewController alloc] init...];
MyAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate.transitionController transitionToViewController:vc withOptions:UIViewAnimationOptionTransitionFlipFromRight];
}
편집: 아래의 원본 답변 - 포테이트 방향으로만 작동합니다.
이 예에 대해 다음과 같은 가정을 했습니다.
가 보기컨다같할다니습으로 .
rootViewController의 창문의새 뷰로 전환할 때 현재 뷰 컨트롤러를 새 뷰를 소유하는 뷰 컨트롤러로 바꾸려고 합니다.언제든지 현재 뷰 컨트롤러만 활성화됩니다(예: 할당됨).
코드는 쉽게 수정하여 다르게 작동할 수 있으며, 핵심은 애니메이션 전환과 단일 뷰 컨트롤러입니다.뷰 컨트롤러를 할당하는 것 외에 다른 곳에 보유하지 않도록 합니다.window.rootViewController.
앱 대리자에서 전환을 애니메이션화하는 코드
- (void)transitionToViewController:(UIViewController *)viewController
withTransition:(UIViewAnimationOptions)transition
{
[UIView transitionFromView:self.window.rootViewController.view
toView:viewController.view
duration:0.65f
options:transition
completion:^(BOOL finished){
self.window.rootViewController = viewController;
}];
}
뷰 컨트롤러에서의 사용 예
- (IBAction)flipToNextView
{
AnotherViewController *anotherVC = [[AnotherVC alloc] init...];
MyAppDelegate *appDelegate = (MyAppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate transitionToViewController:anotherVC
withTransition:UIViewAnimationOptionTransitionFlipFromRight];
}
Apple의 새 viewController 억제 시스템을 사용할 수 있습니다. 비디오 자내은용세한 WWDC 2011"을 하십시오.UIViewController봉쇄".
의 새로운 기능, iOS5 버전,UIViewControllerContainment를 사용하면 상위 뷰Controller와 그 안에 포함된 여러 하위 뷰Controller를 가질 수 있습니다.이것이 UISplitView 컨트롤러의 작동 방식입니다.이렇게 하면 뷰 컨트롤러를 상위에 쌓을 수 있지만 특정 응용 프로그램의 경우 상위를 사용하여 표시되는 뷰 컨트롤러에서 다른 뷰 컨트롤러로의 전환을 관리할 뿐입니다.이것은 Apple에서 승인한 작업 방식이며 한 아이 뷰에서 애니메이션 컨트롤러는 고통이 없습니다. 모든 것을 사용할 수 있습니다.UIViewAnimationOption전환!
또한 UIViewContainment를 사용하면 오리엔테이션 이벤트 중에 하위 뷰 컨트롤러를 관리할 때 발생하는 혼란에 대해 걱정할 필요가 없습니다.다음을 사용하여 상위 ViewController가 순환 이벤트를 하위 ViewController로 전달하는지 확인할 수 있습니다.
- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers{
return YES;
}
부모의 viewDidLoad 메서드에서 다음 또는 유사한 작업을 수행하여 첫 번째 자식ViewController를 설정할 수 있습니다.
[self addChildViewController:self.currentViewController];
[self.view addSubview:self.currentViewController.view];
[self.currentViewController didMoveToParentViewController:self];
[self.currentViewController.swapViewControllerButton setTitle:@"Swap" forState:UIControlStateNormal];
그런 다음 하위 뷰 컨트롤러를 변경해야 할 경우 상위 뷰 컨트롤러 내에서 다음 행을 따라 무언가를 호출합니다.
-(void)swapViewControllers:(childViewController *)addChildViewController:aNewViewController{
[self addChildViewController:aNewViewController];
__weak __block ViewController *weakSelf=self;
[self transitionFromViewController:self.currentViewController
toViewController:aNewViewController
duration:1.0
options:UIViewAnimationOptionTransitionCurlUp
animations:nil
completion:^(BOOL finished) {
[aNewViewController didMoveToParentViewController:weakSelf];
[weakSelf.currentViewController willMoveToParentViewController:nil];
[weakSelf.currentViewController removeFromParentViewController];
weakSelf.currentViewController=[aNewViewController autorelease];
}];
}
저는 전체 예시 프로젝트를 여기에 올렸습니다. https://github.com/toolmanGitHub/stackedViewControllers .이 다른 프로젝트는 사용 방법을 보여줍니다.UIViewController일부 다양한 입력 보기에 포함전체 화면을 차지하지 않는 컨트롤러 유형.행운을 빌어요
알겠습니다, 내비게이션 컨트롤러를 사용하지 않고 질문에 답하는 것은 알지만, 그럴 이유는 없습니다.OP가 제가 잠들기 전에 댓글을 달지 않았어요.저를 부결시키지 마세요.:)
탐색 컨트롤러를 사용하여 현재 보기 컨트롤러를 팝업하고 새 보기 컨트롤러로 전환하는 방법은 다음과 같습니다.
UINavigationController *myNavigationController = self.navigationController;
[[self retain] autorelease];
[myNavigationController popViewControllerAnimated:NO];
PreferencesViewController *controller = [[PreferencesViewController alloc] initWithNibName:nil bundle:nil];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: 0.65];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:myNavigationController.view cache:YES];
[myNavigationController pushViewController:controller animated:NO];
[UIView commitAnimations];
[controller release];
이 정확한 문제를 우연히 발견하고 제한된 성공에 대한 기존의 모든 답변에 대해 변형을 시도했기 때문에, 어떻게 최종적으로 문제를 해결했는지 게시하겠습니다.
이 맞춤형 segue에 대한 게시물에서 설명한 것처럼, 실제로 맞춤형 segue를 만드는 것은 정말 쉽습니다.또한 Interface Builder에서 매우 쉽게 연결되고 IB의 관계를 가시적으로 유지하며 segue의 소스/대상 뷰 컨트롤러의 많은 지원이 필요하지 않습니다.
위에 링크된 게시물은 내비게이션 컨트롤러 스택의 현재 상단 뷰 컨트롤러를 슬라이드 인 탑 애니메이션을 사용하여 새 컨트롤러로 교체할 수 있는 iOS 4 코드를 제공합니다.
나의 경우, 나는 유사한 교체 세그가 일어나기를 원했지만,FlipFromLeft전이.또한 iOS 5+에 대한 지원만 필요했습니다.코드:
RAFlipReplaceSegue에서.h:
#import <UIKit/UIKit.h>
@interface RAFlipReplaceSegue : UIStoryboardSegue
@end
RAFlipReplaceSegue.m에서:
#import "RAFlipReplaceSegue.h"
@implementation RAFlipReplaceSegue
-(void) perform
{
UIViewController *destVC = self.destinationViewController;
UIViewController *sourceVC = self.sourceViewController;
[destVC viewWillAppear:YES];
destVC.view.frame = sourceVC.view.frame;
[UIView transitionFromView:sourceVC.view
toView:destVC.view
duration:0.7
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:^(BOOL finished)
{
[destVC viewDidAppear:YES];
UINavigationController *nav = sourceVC.navigationController;
[nav popViewControllerAnimated:NO];
[nav pushViewController:destVC animated:NO];
}
];
}
@end
이제 컨트롤을 끌어서 다른 종류의 segue를 설정한 다음 Custom segue로 만들고 Custom segue 클래스의 이름을 입력합니다. et voila!
저는 오랫동안 이 문제와 씨름했는데, 제 문제 중 하나가 여기 나열되어 있습니다. 당신이 그런 문제를 겪었는지 모르겠습니다.하지만 iOS 4에서 작동해야 한다면 다음과 같이 추천합니다.
먼저, 새 항목을 만듭니다.NavigationController클래스. 여기서 모든 더러운 작업을 수행합니다. 다른 클래스는 다음과 같은 인스턴스 메서드를 "깨끗하게" 호출할 수 있습니다.pushViewController:등등.당신의.h:
@interface NavigationController : UIViewController {
NSMutableArray *childViewControllers;
UIViewController *currentViewController;
}
- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL))completion;
- (void)addChildViewController:(UIViewController *)childController;
- (void)removeChildViewController:(UIViewController *)childController;
하위 뷰 컨트롤러 어레이는 스택의 모든 뷰 컨트롤러에 대한 저장소 역할을 합니다.모든 회전 및 크기 조정 코드를 자동으로 전달합니다.NavigationController에서 견해의한에대▁to▁thecurrentController.
이제 구현에서 다음을 수행합니다.
- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL))completion
{
currentViewController = [toViewController retain];
// Put any auto- and manual-resizing handling code here
[UIView animateWithDuration:duration animations:animations completion:completion];
[fromViewController.view removeFromSuperview];
}
- (void)addChildViewController:(UIViewController *)childController {
[childViewControllers addObject:childController];
}
- (void)removeChildViewController:(UIViewController *)childController {
[childViewControllers removeObject:childController];
}
만의 사용자 정의를 할 수 .pushViewController:,popViewController이 메서드 호출을 사용합니다.
행운을 빌어요, 그리고 이것이 도움이 되길 바랍니다!
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UINavigationController *viewController = (UINavigationController *)[storyboard instantiateViewControllerWithIdentifier:@"storyBoardIdentifier"];
viewController.modalTransitionStyle = UIModalTransitionStylePartialCurl;
[self presentViewController:viewController animated:YES completion:nil];
이 코드를 사용해 보십시오.
이 코드는 보기 컨트롤러에서 탐색 컨트롤러가 있는 다른 보기 컨트롤러로 전환을 제공합니다.
언급URL : https://stackoverflow.com/questions/8146253/animate-change-of-view-controllers-without-using-navigation-controller-stack-su
'code' 카테고리의 다른 글
| CSV 파일과 함께 사용할 수 있는 최소 학습 곡선 (0) | 2023.06.12 |
|---|---|
| ipython의 내 플롯은 pyplot.show()와 함께 표시되지 않습니다. (0) | 2023.06.12 |
| PHP의 "비개체에 대한 속성 가져오기 시도" (0) | 2023.06.12 |
| TypeScript에서 React 구성 요소 확장 (0) | 2023.06.12 |
| C의 2D 배열 포인터 (0) | 2023.06.12 |