Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/95.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 淡入状态栏文本而不删除状态栏本身_Ios_Swift_Statusbar_Alpha - Fatal编程技术网

Ios 淡入状态栏文本而不删除状态栏本身

Ios 淡入状态栏文本而不删除状态栏本身,ios,swift,statusbar,alpha,Ios,Swift,Statusbar,Alpha,我想隐藏状态栏文本而不删除状态栏本身 我正在全屏显示一个新的视图控制器,我不希望状态栏文本在视图控制器接管全屏时可见。请注意,呈现视图控制器有一个UINavigationBar,而呈现视图控制器没有 我曾尝试在prefersStatusBarHidden中简单地返回true,但这会导致状态栏框架被删除,导致演示视图控制器上的导航控制器向上滑动,并且在新视图控制器仍从底部向上动画时,这是可见的 然后,我尝试将显示的视图控制器的modalPresentationCapturesStatusBarAp

我想隐藏状态栏文本而不删除状态栏本身


我正在全屏显示一个新的视图控制器,我不希望状态栏文本在视图控制器接管全屏时可见。请注意,呈现视图控制器有一个
UINavigationBar
,而呈现视图控制器没有

我曾尝试在
prefersStatusBarHidden
中简单地返回
true
,但这会导致状态栏框架被删除,导致演示视图控制器上的导航控制器向上滑动,并且在新视图控制器仍从底部向上动画时,这是可见的

然后,我尝试将显示的视图控制器的
modalPresentationCapturesStatusBarAppearance
设置为
true
,然后在
PreferenceStatusBarHidden
中返回
false
,在
preferredStatusBarUpdateAnimation
中调用
SetNeedssStatusBarAppearanceUpdate()
视图中出现
,但这会导致状态栏文本从白色变为黑色并保持可见。将
prefersStatusBarHidden
设置为
true
将删除我前面提到的状态栏


理想情况下,我会在启动segue时开始淡入状态栏上的文本,动画完成时alpha将达到0。然后在被解雇后,回到阿尔法1。这是可能的还是类似的解决方案?我只需要支持iOS 8+。

解决方案1:我的解决方案非常粗糙,但很有效。首先,显示的视图控制器应将
modalPresentationCapturesStatusBarAppearance
设置为
YES
,并应返回
YES
作为
首选状态BarHidden

现在,问题是导航栏不能向上滑动。为此,首先子类
UINavigationBar
并覆盖
setFrame:
setBounds:
、和
setCenter:
以保持导航栏的形状和位置固定,即使当状态栏隐藏时导航栏想要向上滑动。大概是这样的:

const CGFloat kStatusBarHeight = 20;
const CGFloat kDefaultNavigationBarHeight = 44;
const CGFloat kLandscapeNavigationBarHeight = 32;

...

- (void)setCenter:(CGPoint)center {
    center = [self forcedCenterForCenter:center];
    [super setCenter:center];
}

- (void)setBounds:(CGRect)bounds {
    bounds = [self forcedBoundsForBounds:bounds];
    [super setBounds:bounds];
}

- (void)setFrame:(CGRect)frame {
    frame = [self forcedFrameForFrame:frame];
    [super setFrame:frame];
}

- (CGPoint)forcedCenterForCenter:(CGPoint)center {
    if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) {
        center.y = kStatusBarHeight + kDefaultNavigationBarHeight * 0.5;
    }
    else {
        // No status bar in landscape orientation in iOS 8.
        center.y = kLandscapeNavigationBarHeight * 0.5;
    }

    return center;
}

- (CGRect)forcedBoundsForBounds:(CGRect)bounds {
    if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) {
        bounds.size.height = kDefaultNavigationBarHeight;
    }
    else {
        bounds.size.height = kLandscapeNavigationBarHeight;
    }

    return bounds;
}

- (CGRect)forcedFrameForFrame:(CGRect)frame {
    if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) {
        frame.origin.y = kStatusBarHeight;
        frame.size.height = kDefaultNavigationBarHeight;
    }
    else {
        // No status bar in landscape orientation in iOS 8.
        frame.origin.y = 0.0;
        frame.size.height = kLandscapeNavigationBarHeight;
    }

    return frame;
}
让我们调用这个类
ForcedNavigationBar
。如果您只是将该类传递到
UINavigationController
initWithNavigationBarClass:toolbarClass:
,导航栏将保持不变,但会遇到其他问题。首先,有时,导航栏不会向上延伸以在状态栏的下方进行覆盖。其次,推到导航控制器上的视图控制器不应再使用其
topLayoutGuide
属性进行布局,因为
topLayoutGuide
可能会考虑到状态栏实际上已被隐藏,即使我们总是强制为假想的状态栏留出空间

要解决第一个问题,首先将
ForcedNavigationBar
backgroundColor
属性设置为
[UIColor clearColor]
并覆盖
drawRect:
使其背景不可见(不调用
super
)。(导航栏的按钮仍然可见。)现在,我们在真实导航栏下放置一个虚拟导航栏,以提供一个背景,该背景将始终位于虚拟状态栏空间的下方。我们可以通过子类化
UINavigationController
(称之为
ForcedNavigationBar
)并向虚拟导航栏添加约束来实现这一点:

- (void)viewDidLoad {
    [super viewDidLoad];

    UINavigationBar * backgroundNavigationBar = [[UINavigationBar alloc] init];
    [self.navigationBar.superview insertSubview:backgroundNavigationBar belowSubview:self.navigationBar];
    {
        backgroundNavigationBar.translatesAutoresizingMaskIntoConstraints = NO;

        // The background bar always hugs the top of the screen.
        NSLayoutConstraint * topConstraint = [NSLayoutConstraint constraintWithItem:backgroundNavigationBar
                                                                          attribute:NSLayoutAttributeTop
                                                                          relatedBy:NSLayoutRelationEqual
                                                                             toItem:self.view
                                                                          attribute:NSLayoutAttributeTop
                                                                         multiplier:1
                                                                           constant:0];
        [self.view addConstraint:topConstraint];

        NSLayoutConstraint * bottomConstraint = [NSLayoutConstraint constraintWithItem:backgroundNavigationBar
                                                                             attribute:NSLayoutAttributeBottom
                                                                             relatedBy:NSLayoutRelationEqual
                                                                                toItem:self.navigationBar
                                                                             attribute:NSLayoutAttributeBottom
                                                                            multiplier:1
                                                                              constant:0];
        [self.navigationBar.superview addConstraint:bottomConstraint];

        NSLayoutConstraint * leftConstraint = [NSLayoutConstraint constraintWithItem:backgroundNavigationBar
                                                                           attribute:NSLayoutAttributeLeft
                                                                           relatedBy:NSLayoutRelationEqual
                                                                              toItem:self.navigationBar
                                                                           attribute:NSLayoutAttributeLeft
                                                                          multiplier:1
                                                                            constant:0];
        [self.navigationBar.superview addConstraint:leftConstraint];

        NSLayoutConstraint * rightConstraint = [NSLayoutConstraint constraintWithItem:backgroundNavigationBar
                                                                            attribute:NSLayoutAttributeRight
                                                                            relatedBy:NSLayoutRelationEqual
                                                                               toItem:self.navigationBar
                                                                            attribute:NSLayoutAttributeRight
                                                                           multiplier:1
                                                                             constant:0];
        [self.navigationBar.superview addConstraint:rightConstraint];
    }
}
要解决第二个问题,只需不使用
topLayoutGuide
,而是根据导航栏的位置设置顶部的空间。对于不是滚动视图的视图,可以更新相对于
viewWillLayoutSubviews
中导航栏定位这些视图的约束。如果您有一个滚动视图(如表格视图),则可以在
viewdilayoutsubview
中调整其
contentInset
的顶部。(以前,您应该将滚动视图的
contentInset
顶部设置为
topLayoutGuide.length

我提供的代码可以在iPhone5屏幕上运行。在iOS 8中,您必须使此代码“自适应”,这样它在iPhone 6屏幕上仍然可以工作。例如,在横向定位中,iPhone 6上的导航栏可能没有挤压

编辑:解决方案2:使用
SnapshotViewAfterScreenuUpdate
拍摄演示视图控制器的快照视图,并在演示或取消之前将其插入视图层次结构中。这样,您就不必担心导航栏会上下滑动。(我个人还没有尝试过,但似乎很有希望。)


编辑2:此解决方案的一个小问题是,在取消之前,导航栏将没有空间放置状态栏。如果您使用
UIViewControllerAnimatedTransitioning
进行解雇,则使用空动画块调用
[UIView animationionwithduration:…]
似乎(以某种方式)强制系统让“to”视图控制器(导航控制器)指定状态栏外观。然后,要使“to”视图控制器布局并为状态栏留出空间,可以在容器视图或其中包含“to”视图控制器的某个视图上调用
layoutifneed
。在
animateTransition:
中执行所有这些操作,但在使用此方法实际执行动画之前。

实际上,您可以直接使用状态栏访问窗口,并对其执行任何操作

- (UIWindow *)statusBarWindow
{
    return (UIWindow *)[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"];
}

当然,它是未记录的功能,在应用程序审查过程中可能会有危险,但我对此只有积极的经验。

“请注意,演示视图控制器有一个UINavigationBar,而演示视图控制器没有。”您意识到这是一个矛盾吗