네비게이션 컨트롤러의 투명한 모달 뷰
내 탐색 컨트롤러 위에 투명한 모달 뷰를 만들려고합니다. 이것이 가능한지 아는 사람이 있습니까?
모달보기는 내비게이션 컨트롤러의 내비게이션 바뿐만 아니라 상단에 푸시 된보기를 포함합니다. 그러나 -presentModalViewController : animated : 접근 방식을 사용하면 애니메이션이 완료되면 방금 덮힌 뷰가 실제로 사라져 모달 뷰의 투명성을 무의미하게 만듭니다. (루트 뷰 컨트롤러에서 -viewWillDisappear : 및 -viewDidDisappear : 메소드를 구현하여이를 확인할 수 있습니다).
다음과 같이 모달 뷰를 뷰 계층 구조에 직접 추가 할 수 있습니다.
UIView *modalView =
[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
modalView.opaque = NO;
modalView.backgroundColor =
[[UIColor blackColor] colorWithAlphaComponent:0.5f];
UILabel *label = [[[UILabel alloc] init] autorelease];
label.text = @"Modal View";
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor clearColor];
label.opaque = NO;
[label sizeToFit];
[label setCenter:CGPointMake(modalView.frame.size.width / 2,
modalView.frame.size.height / 2)];
[modalView addSubview:label];
[self.view addSubview:modalView];
이와 같이 루트 뷰에 대한 하위 뷰로 modalView를 추가하면 실제로 내비게이션 바를 덮지는 않지만 그 아래의 전체 뷰를 덮을 것입니다. modalView를 초기화하는 데 사용 된 프레임의 원점을 가지고 놀았지만 음수 값으로 인해 표시되지 않습니다. 상태 표시 줄 외에 전체 화면을 덮는 가장 좋은 방법은 modalView를 창 자체의 하위보기로 추가하는 것입니다.
TransparentModalViewAppDelegate *delegate = (TransparentModalViewAppDelegate *)[UIApplication sharedApplication].delegate;
[delegate.window addSubview:modalView];
가장 쉬운 방법은 navigationController의 modalPresentationStyle 속성 을 사용하는 것 입니다 (하지만 애니메이션을 직접 만들어야합니다).
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalViewController animated:NO];
modalViewController.view.alpha = 0;
[UIView animateWithDuration:0.5 animations:^{
modalViewController.view.alpha = 1;
}];
내 창 또는 루트보기의 다른 모든 하위보기 위에있는 "OverlayViewController"를 설정하여이 작업을 가장 쉽게 수행합니다. 앱 델리게이트 또는 루트 뷰 컨트롤러에서이를 설정하고 OverlayViewController를 싱글 톤으로 만들어 코드 또는 뷰 컨트롤러 계층 구조의 어느 곳에서나 액세스 할 수 있도록합니다. 그런 다음 필요할 때마다 메서드를 호출하여 모달보기를 표시하고 활동 표시기를 표시 할 수 있으며 잠재적으로 모든 탭 표시 줄 또는 탐색 컨트롤러를 덮을 수 있습니다.
루트 뷰 컨트롤러의 샘플 코드 :
- (void)viewDidLoad {
OverlayViewController *o = [OverlayViewController sharedOverlayViewController];
[self.view addSubview:o.view];
}
모달보기를 표시하는 데 사용할 수있는 샘플 코드 :
[[OverlayViewController sharedOverlayViewController] presentModalViewController:myModalViewController animated:YES];
실제로 -presentModalViewController:animated:
OverlayViewController와 함께 사용 하지는 않았지만 이것이 잘 작동 할 것으로 기대합니다.
참조 : Objective-C 싱글 톤은 어떻게 생겼습니까?
나는이 같은 문제가 있었고 해결책은 addSubview :를 사용하여 모달 뷰를 추가하고 UIView의 animateWithDuration : delay : options : animations : completion을 사용하여 뷰 계층 구조의 변경 사항을 애니메이션하는 것입니다.
다른 기능을 포함하는 UIViewController (FRRViewController)의 하위 클래스에 속성과 2 개의 메서드를 추가했습니다. 곧 gitHub에 전체 내용을 게시 할 예정이지만 그때까지 아래 관련 코드를 볼 수 있습니다. 자세한 내용은 내 블로그 에서 투명 모달 뷰 컨트롤러를 표시하는 방법을 확인할 수 있습니다 .
#pragma mark - Transparent Modal View
-(void) presentTransparentModalViewController: (UIViewController *) aViewController
animated: (BOOL) isAnimated
withAlpha: (CGFloat) anAlpha{
self.transparentModalViewController = aViewController;
UIView *view = aViewController.view;
view.opaque = NO;
view.alpha = anAlpha;
[view.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UIView *each = obj;
each.opaque = NO;
each.alpha = anAlpha;
}];
if (isAnimated) {
//Animated
CGRect mainrect = [[UIScreen mainScreen] bounds];
CGRect newRect = CGRectMake(0, mainrect.size.height, mainrect.size.width, mainrect.size.height);
[self.view addSubview:view];
view.frame = newRect;
[UIView animateWithDuration:0.8
animations:^{
view.frame = mainrect;
} completion:^(BOOL finished) {
//nop
}];
}else{
view.frame = [[UIScreen mainScreen] bounds];
[self.view addSubview:view];
}
}
-(void) dismissTransparentModalViewControllerAnimated:(BOOL) animated{
if (animated) {
CGRect mainrect = [[UIScreen mainScreen] bounds];
CGRect newRect = CGRectMake(0, mainrect.size.height, mainrect.size.width, mainrect.size.height);
[UIView animateWithDuration:0.8
animations:^{
self.transparentModalViewController.view.frame = newRect;
} completion:^(BOOL finished) {
[self.transparentModalViewController.view removeFromSuperview];
self.transparentModalViewController = nil;
}];
}
}
문제를 해결하기 위해 내가 한 일은 다음과 같습니다. 세부 사항은 Google이지만이 접근 방식은 저에게 매우 효과적이었습니다.
- 기본보기의 스크린 샷을 찍습니다. https://devforums.apple.com/message/266836- 현재 화면에 대한 UIView를 반환하는 기성 메서드로 이어집니다.
- 모달보기에 스크린 샷 전달 (속성 사용)
- 모달보기 표시
- 모달 뷰 컨트롤러의 viewDidAppear에서 인덱스 0에서 이미지를 UIImageView로 설정합니다. 상태 표시 줄의 높이로 이미지의 수직 위치를 조정합니다.
- 모달 뷰 컨트롤러의 viewWillDisappear에서 이미지를 다시 제거하십시오.
효과는 다음과 같습니다.
- 모든 모달 뷰와 마찬가지로 뷰가 애니메이션됩니다. 모달 뷰의 반투명 부분이 기존 뷰 위로 미끄러집니다.
- 애니메이션이 중지 되 자마자 배경이 스크린 샷으로 설정됩니다. 이렇게하면 이전 뷰가 그렇지 않더라도 여전히 아래에있는 것처럼 보입니다.
- 모달 뷰의 사라짐 애니메이션이 시작되면 이미지가 제거됩니다. 한편 OS는 이전 탐색보기를 표시하므로 모달보기가 예상대로 투명하게 미끄러 져 보이지 않습니다.
내 오버레이 뷰에서 애니메이션을 시도했지만 잘 작동하지 않았습니다. 무엇이 충돌했는지에 대한 표시없이 충돌이 발생했습니다. 이것을 추격하는 대신 bg view & Works를 정말 잘했습니다.
모달보기의 코드-나머지는 알아낼 수 있다고 생각합니다. 즉, modalView.bgImage 속성을 설정합니다.
- (void)viewDidAppear:(BOOL)animated {
// background
// Get status bar frame dimensions
CGRect statusBarRect = [[UIApplication sharedApplication] statusBarFrame];
UIImageView *imageView = [[UIImageView alloc] initWithImage:self.bgImage];
imageView.tag = 5;
imageView.center = CGPointMake(imageView.center.x, imageView.center.y - statusBarRect.size.height);
[self.view insertSubview:imageView atIndex:0];
}
- (void)viewWillDisappear:(BOOL)animated {
[[self.view viewWithTag:5] removeFromSuperview];
}
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:newview animated:YES];
모달 뷰 배경을 투명하게 설정했는지 확인하세요.
self.view.background = .... alpha : 0.x;
모달 뷰 컨트롤러에 대해 modalPresentationStyle을 다음과 같이 설정 한 경우 :
viewController.modalPresentationStyle = 17;
백그라운드의보기는 제거되지 않습니다. (TWTweetComposeViewController가 사용합니다).
이 코드로 App Store 리뷰를 통과하려고 시도하지 않았습니다.
반투명 한 "로드 중 ..."보기 표시에 대한이 게시물은 진행 방법에 대한 몇 가지 지침을 제공 할 수 있습니다.
예, 뷰를 수동으로 추가해야합니다. 아래쪽에서 슬라이드하려는 경우 또는 애니메이션을 직접 수행해야합니다.
이 작업을 수행하는 클래스와 해당 클래스를 예로 사용하는 세미 모달 날짜 선택기를 작성했습니다.
이 블로그 게시물 에서 문서를 찾을 수 있으며 코드는 github에 있습니다.
나는 지난주 동안이 같은 문제를 조사해 왔습니다. Google과 여기 StackOverflow에서 찾은 다양한 답변과 예제를 모두 시도했습니다. 그들 중 누구도 그렇게 잘 작동하지 않았습니다.
iOS 프로그래밍을 처음 접했기 때문에 UIActionSheet
. 따라서 버튼의 모달 오버레이를 표시하기 위해이를 수행하려는 경우 (예 : 누군가에게 무엇을 공유 할 것인지 묻는 모달)을 사용하십시오 UIActionSheet
.
다음은 이를 수행하는 방법의 예를 보여주는 웹 페이지입니다 .
이 아이디어는 https://gist.github.com/1279713 에서 얻었습니다.
준비 : 모달보기 xib (또는 스토리 보드를 사용하는 장면)에서 0.3 알파로 전체 화면 배경 UIImageView (.h 파일에 연결하고 속성 "backgroundImageView"를 부여)를 설정했습니다. 그리고 뷰 (UIView) 배경색을 일반 검정색으로 설정했습니다.
아이디어 : 그런 다음 모달 뷰 컨트롤러의 "viewDidLoad"에서 원래 상태에서 스크린 샷을 캡처하고 해당 이미지를 배경 UIImageView로 설정합니다. 초기 Y 포인트를 -480으로 설정하고 EaseInOut 애니메이션 옵션을 사용하여 0.4 초 기간을 사용하여 Y 포인트 0으로 슬라이드하도록합니다. 뷰 컨트롤러를 닫을 때 반대의 작업을 수행하십시오.
모달 뷰 컨트롤러 클래스에 대한 코드
.h 파일 :
@property (weak, nonatomic) IBOutlet UIImageView *backgroundImageView;
- (void) backgroundInitialize;
- (void) backgroundAnimateIn;
- (void) backgroundAnimateOut;
.m 파일 :
- (void) backgroundInitialize{
UIGraphicsBeginImageContextWithOptions(((UIViewController *)delegate).view.window.frame.size, YES, 0.0);
[((UIViewController *)delegate).view.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
backgroundImageView.image=screenshot;
}
- (void) backgroundAnimateIn{
CGRect backgroundImageViewRect = backgroundImageView.frame;
CGRect backgroundImageViewRectTemp = backgroundImageViewRect;
backgroundImageViewRectTemp.origin.y=-480;
backgroundImageView.frame=backgroundImageViewRectTemp;
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationCurveEaseInOut animations:^{
backgroundImageView.frame=backgroundImageViewRect;
} completion:^(BOOL finished) {
}];
}
- (void) backgroundAnimateOut{
CGRect backgroundImageViewRect = backgroundImageView.frame;
backgroundImageViewRect.origin.y-=480;
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationCurveEaseInOut animations:^{
backgroundImageView.frame=backgroundImageViewRect;
} completion:^(BOOL finished) {
}];
}
viewDidLoad에서 다음을 호출하면됩니다.
[self backgroundInitialize];
[self backgroundAnimateIn];
모달 뷰 컨트롤러를 닫으면 어디에서나 다음을 호출합니다.
[self backgroundAnimateOut];
이것은 항상 배경 이미지에 애니메이션을 적용합니다. 따라서이 모달 뷰 컨트롤러 전환 스타일 (또는 segue 전환 스타일)이 "Cover Vertical"로 설정되지 않은 경우 애니메이션 메서드를 호출 할 필요가 없습니다.
I finally accomplished this, for a navigation or tab bar interface, by combining an overlay view controller (see: pix0r's answer) that's hidden / un-hidden before hiding or showing a view controller based on this very good blog post.
Concerning the view controller, the tip is to make its background view the clearColor
, then the semi-transparent overlay view is visible and whatever views are added as subviews in the view controller are in front and most importantly opaque.
I've created open soruce library MZFormSheetController to present modal form sheet on additional UIWindow. You can use it to present transparency modal view controller, even adjust the size of the presented view controller.
For iOS 8+ you can use UIModalPresentationOverCurrentContext
presentation style for presented view controller to easy achieve desired behavior.
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.9f];
viewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:viewController animated:YES completion:nil];
If you also need to support iOS 7 - check this thread.
You can achieve transparent/semi-transparent modal view effect by overlaying a transparent/semi-transparent button on both the view and the navigation bar.
You can access the navigation bar through the navigationBar property of the UINavigationController.
I found that UIButton unlike UILabel will trap mouse events - hence giving the correct modal behavior.
I just found a workaround for that. Just create a 1X1 of UIViewController and add it to your parent view controller. And show the transparent modal view controller in that UIViewController.
on viewDidLoad;
self.dummyViewController = [[UIViewController alloc] init]; [self.dummyViewController.view setFrame:CGRectMake(0, 0, 1, 1)]; [self.view addSubView:self.dummyViewController.view];
when you need to open a transparentViewController;
[self.dummyViewController presentModalViewController:yourTransparentModalViewController animated:true];
If you need a screen like the attached one, the below code may help you.
The code:
MyViewController * myViewController = [[MyViewController alloc] initWithNibName:nibName bundle:nil];
UINavigationController * myNavigationController = [[UINavigationController alloc] initWithRootViewController: myViewController];
myNavigationController.modalPresentationStyle = UIModalPresentationPageSheet;
[self presentModalViewController: myNavigationController animated:YES];
If say you want a screen overlay, use the parentViewController.view, it will place above navigation bar ++
MyCustomViewController* myOverlayView = [[MyCustomViewController alloc] init]; [self.parentViewController.view addSubview:myOverlayView];
This worked for me:
UIViewController *modalViewController = [[UIViewController alloc] init];
modalViewController.view.backgroundColor = [UIColor whiteColor] colorWithAlpha:0.5];
[self showDetailViewController:modalViewController sender:nil];
참고URL : https://stackoverflow.com/questions/849458/transparent-modal-view-on-navigation-controller
'Nice programing' 카테고리의 다른 글
Html Agility Pack은 클래스별로 모든 요소를 가져옵니다. (0) | 2020.10.28 |
---|---|
TypeError 가져 오기 : __init __ () 필수 위치 인수 1 개 누락 : 항목이있는 자식 테이블 뒤에 부모 테이블을 추가하려고 할 때 'on_delete' (0) | 2020.10.28 |
루트에서 하위 디렉터리로 IIS7 URL 리디렉션 (0) | 2020.10.28 |
파이썬에서 신호에 잡음 추가 (0) | 2020.10.28 |
document.createElement ( "script") 동기식 (0) | 2020.10.28 |