【问题标题】:Transparent ViewController透明视图控制器
【发布时间】:2013-12-21 01:30:58
【问题描述】:

我正在用

推送一个 UIViewController
[otherController presentViewController: newController animated: NO completion: nil];

然后 newController 的 nib 具有基本视图、一个较小的视图和一个文本字段以及较小视图中的一些按钮。我希望基础视图是透明的灰色,这样我就可以看到它下面的视图控制器的视图,同时让用户可以清楚地看到其他视图已被禁用。

我尝试将 Alpha 值设置为低(它对我的其他控件进行了 alpha 化处理),将视图背景设置为透明黑色,并取消设置不透明标志。这些都不起作用。我只是得到一个不透明的浅灰色背景。

这是我的视图控制器:

@interface MyEditQueryViewController : UIViewController

@property (nonatomic, strong) id<MyEditQueryDelegate> delegate;
@property (nonatomic, strong) IBOutlet UITextField* textField;
@property (nonatomic, strong) IBOutlet UIView* editView;
@property (nonatomic, strong) IBOutlet UIButton* cancelButton;
@property (nonatomic, strong) IBOutlet UIButton* saveButton;
@property (nonatomic, strong) NSString* defaultText;
@property (nonatomic) CGFloat verticalOffset;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;
- (id)initWithDefaultText:(NSString*)defaultText orign:(CGPoint)origin;

- (IBAction)cancelTapped:(id)sender;
- (IBAction)saveTapped:(id)sender;
@end

有没有办法让那个视图变成半透明的?

【问题讨论】:

    标签: ios uiviewcontroller


    【解决方案1】:

    iPhone 上,完成此操作的唯一方法(在UIAlertViewUIActionSheet 之外)是将UIView 作为UIViewController 上的子视图呈现,该UIViewController 将用作背景视图。您呈现的UIView 可以占据全屏,并在大部分视图中使用透明/半透明视图来完成调光效果。


    iPad 上,除了UIAlertViewUIActionSheet,您还可以模态呈现非全屏视图。它们有自己的视图控制器。为此,您需要将UIModalPresentationStyle 设置为以下之一:

    • UIModalPresentationPageSheet

    • UIModalPresentationFormSheet

    但是,这两个选项(在我看来)在如何调整它们的大小和放置它们的位置方面都有一些限制,因此如果您想要完全自定义,则必须以相同的方式进行我通过在用作背景视图的UIViewController 上显示单独的UIView 来解释iPhone。


    除了 iPad 的 UIModalPresentationPageSheetUIModalPresentationFormSheet 选项外,为视图控制器设置透明/半透明背景将假定您可以设置颜色的最后一层后面是白色背景。


    还应注意UIAlertViewUIActionSheet 旨在(由Apple)按原样使用并且不应被子类化,而您可以将UIView 子类化为您想要的所有您想要的任何外观。

    【讨论】:

    • 你是说除了 UIViewController 默认拥有的 UIView 之外的 UIView 吗?
    • 是的。将子视图添加到UIViewControllerview
    • 在笔尖中,我在“视图”下添加了一个 Alpha:0.5 和黑色背景的视图,但我仍然看不到另一个视图控制器的内容。都是灰色的。
    • 我做到了。除非你想说的不是你所说的,否则它是行不通的。
    • @JasperBlues 在工作中,我使用的方法类似于您的答案解释......主要是因为我需要在其他几个视图控制器中使用相同的视图,但我的答案提供了kwiqsilver 想要实现的效果的最基本实现。
    【解决方案2】:

    当使用自定义的 RootViewController 来管理自己的容器视图时,这种事情很容易。然后根视图控制器可以定义自己的导航系统或委托给标准的 UIKit 组件。

    这还具有能够使用域特定语言的优势 - 在 Root VC 的界面中为您的特定应用程序建模的方法名称 - 例如 [rootViewController presentMenuItem:menuItem]。

    我有一个使用根视图控制器here 的应用示例。

    这是另一个代码 sn-p(来自另一个应用程序),它显示了具有半透明背景的叠加层:

    - (void)presentOverlayViewController:(UIViewController*)viewController
    {
        LogDebug(@"Presenting overlay view controller: %@", viewController);
        if (_overlayViewController)
        {
            [self dismissOverlayViewController];
        }
    
        [self.view setUserInteractionEnabled:NO];
        [self.view bringSubviewToFront:_tintView];
        [_tintView setAlpha:0.0];
        [self.view bringSubviewToFront:_overlayViewContainer];
        _overlayViewController = viewController;
    
        CGSize screenSize = [[UIScreen mainScreen] currentSize];
    
        [viewController willMoveToParentViewController:self];
        [_overlayViewContainer addSubview:viewController.view];
        [_overlayViewController.view setPosition:(CGPoint) {(screenSize.width / 2) - (_overlayViewController.view.frame.size.width / 2),
                (screenSize.height / 2) - (_overlayViewController.view.frame.size.height / 2)}];
    
        __weak UIView* overlayViewContainer = _overlayViewContainer;
        __weak UIView* view = self.view;
        __weak UIView* tintView = _tintView;
        [UIView transitionWithView:self.view duration:0.60 options:UIViewAnimationOptionCurveEaseInOut animations:^
        {
            [tintView setAlpha:0.7];
            CGRect newFrame = overlayViewContainer.frame;
            newFrame.origin.y -= screenSize.height;
            [overlayViewContainer setUserInteractionEnabled:YES];
            overlayViewContainer.frame = newFrame;
        } completion:^(BOOL complete)
        {
            [viewController didMoveToParentViewController:self];
            [view setUserInteractionEnabled:YES];
        }];
    }
    

    这种方法适用于 iOS 或 iPad,实际上可以编写为同时适用于两者。

    编辑:

    如果您没有将自定义根视图控制器设置为 UIWindow 上的 rootVC,您仍然可以通过在将呈现半透明覆盖的 VC 上添加相同的方法来执行此操作。

    编辑2:

    请注意添加:

     [viewController willMoveToParentViewController:self];
     [viewController didMoveToParentViewController:self];
    

    。 .正如 Jesse Rusak 所指出的,这是必需的

    【讨论】:

    • 有道理,但您需要使用 UIViewController 包含 API,而不是仅仅从视图控制器中抓取视图。
    • 是的,还有旋转、视图卸载、事件处理等,在令人惊讶的情况下都会中断或痛苦。在 iOS 5 之前的版本中基本上不支持这样做,因此至少可以用这些 API 找出“正确”的方式来做这件事。
    • 支持子视图,但不支持属于不同视图控制器的子视图。
    • @JesseRusak 哇——我不知道这在 IOS5 之前特别不受支持。我只是认为这是更多的工作。 . .事实上,甚至在 iOS5 之前也使用了相同的方法!无论如何 - 感谢您的提示。
    • 我能找到的最官方的文档来自 Apple 的 UIViewController 文档:“在将子视图的根视图添加到视图层次结构之前,您的容器视图控制器必须与其自身关联一个子视图控制器。”我确信某处的 WWDC 视频中有一些东西...... :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    • 2013-09-24
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 2011-12-14
    • 2010-10-25
    相关资源
    最近更新 更多