iOS 7 - Thanh trạng thái chồng lên chế độ xem


109

Tôi có một ViewControllercái bên trong a UINavigationcontroller, nhưng thanh điều hướng bị ẩn. Khi tôi chạy ứng dụng trên iOS 7, thanh trạng thái hiển thị trên đầu chế độ xem của tôi. Có cách nào để tránh điều này không?

Tôi không muốn viết bất kỳ mã hệ điều hành cụ thể nào.

Nhập mô tả hình ảnh tại đây

Tôi đã thử đặt View controller-based status bar appearancethành NO, nhưng nó không khắc phục được sự cố.


Tôi đã đăng tải câu trả lời của tôi để hiển thị thanh trạng thái như iOS 6 trong iOS 7 stackoverflow.com/questions/18294872/...
Desert Rose

2
Bạn cũng cần điều chỉnh điểm gốc và giá trị delta của y để xử lý vấn đề thanh trạng thái Điều này có thể giúp bạn stackoverflow.com/q/18980925/1545180
Ganapathy

Câu trả lời:


95

Xcode 5 đã iOS 6/7 Deltasđược sản xuất đặc biệt để giải quyết vấn đề này. Trong bảng phân cảnh, tôi đã di chuyển chế độ xem của mình xuống 20 pixel để trông giống với iOS 7 và để tương thích với iOS 6, tôi đã thay đổi Delta ythành -20.

nhập mô tả hình ảnh ở đây

Kể từ khi kịch bản của tôi không sử dụng tính năng tự động bố trí, để thay đổi kích thước chiều cao quan điểm đúng trên iOS 6 tôi đã phải thiết lập Delta heightcũng như Delta Y.


8
câu trả lời của bạn đúng nhưng không hoạt động với màn hình 4 ". Vui lòng cập nhật câu trả lời của bạn nếu bạn cũng có thể làm cho nó hoạt động với màn hình 4". Cảm ơn trước.

2
@AnkitMehta tôi không phải làm gì cả cụ thể cho 4" iphones
aryaxt

5
đã làm cho tôi. Lưu ý rằng để xem các delta này, bạn phải bỏ chọn 'Sử dụng Tự động thanh toán' trong 'Danh tính và Loại' cho bảng phân cảnh.
marsant

2
Tôi phát hiện ra ngoài việc đặt -20 cho ∆Y, tôi cũng phải đặt +20 cho ∆Height
Toland Hon

3
Điều gì xảy ra khi chiều cao thanh trạng thái sẽ thay đổi? F.ex .: Khi người dùng kích hoạt nóng tại chỗ, vv .... sau đó chiều cao là 40px ...
Lukasz

69

Nếu bạn chỉ KHÔNG muốn bất kỳ thanh trạng thái nào, bạn cần cập nhật bảng xếp hạng của mình với dữ liệu này: Để thực hiện việc này, trong bảng xếp hạng, hãy thêm 2 cài đặt đó:

<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

Trong iOS 7, bạn dự kiến ​​sẽ thiết kế ứng dụng của mình với thanh trạng thái trong suốt có lớp phủ. Hãy xem ứng dụng Thời tiết trên iOS 7 mới chẳng hạn.


3
Đây thực sự là câu trả lời tốt duy nhất vì nó khắc phục được vấn đề cốt lõi của nó theo cách nó được thực hiện. Vì vậy: cần có sự ủng hộ!
11 giờ 59

5
Nó có thể thích hợp cho một số trường hợp, nhưng bạn cần phải thật cẩn thận khi ẩn thanh trạng thái. Chỉ dành cho các chế độ xem chính đáng là toàn màn hình, như trình phát phương tiện hoặc trình xem hình ảnh.
smileBot

1
@ eleven59, ý bạn là cách mà những người chuyên quyền ở Apple dự định.
JohnK

1
Chắc chắn như thế này tốt hơn là thay đổi độ lệch của bộ điều khiển chế độ xem (cảm thấy thực sự bẩn).
Benjamin Oman

thanh trạng thái ẩn không phải là một ý tưởng tốt ... Tôi biết điều này là dễ nhất cách để xử lý iOS 7, nhưng thời gian là cần thiết ...
Fahim Parkar

43

Đây là hành vi mặc định UIViewControllertrên iOS 7. Chế độ xem sẽ ở chế độ toàn màn hình, nghĩa là thanh trạng thái sẽ bao phủ đầu chế độ xem của bạn.

Nếu bạn có UIViewControllerbên trong a UINavigationControllervà Thanh điều hướng hiển thị, bạn có thể có mã sau trong của bạn viewDidLoadhoặc có hình nền cho Thanh điều hướng thực hiện thủ thuật.

self.edgesForExtendedLayout = UIRectEdgeNone;

Nếu bạn đã ẩn navigationBar, thì bạn phải điều chỉnh tất cả các phần tử UIView bằng cách dịch chuyển 20 điểm. Tôi không thấy giải pháp nào khác. Sử dụng bố cục tự động sẽ giúp một chút.

Đây là mã mẫu để phát hiện phiên bản iOS, nếu bạn muốn tương thích ngược.

NSUInteger DeviceSystemMajorVersion() {
    static NSUInteger _deviceSystemMajorVersion = -1;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        NSString *systemVersion = [UIDevice currentDevice].systemVersion;
        _deviceSystemMajorVersion = [[systemVersion componentsSeparatedByString:@"."][0] intValue];
    });

   return _deviceSystemMajorVersion;
}

18
Thay vì lấy, phân tích và so sánh các phiên bản hệ thống, nó được khuyến khích để sử dụngif ([self respondsToSelector:@selector(edgesForExtendedLayout)])
Sebastian Hojas

15

Giải pháp duy nhất làm việc mà tôi đã tự thực hiện.

Đây là lớp con UIViewController của tôi https://github.com/comonitos/ios7_overlaping

1 lớp con từ UIViewController

2 Phân lớp window.rootViewController của bạn từ lớp đó.

3 Thì đấy!

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect screen = [[UIScreen mainScreen] bounds];
        if (self.navigationController) {
            CGRect frame = self.navigationController.view.frame;
            frame.origin.y = 20;
            frame.size.height = screen.size.height - 20;
            self.navigationController.view.frame = frame;
        } else {
            if ([self respondsToSelector: @selector(containerView)]) {
                UIView *containerView = (UIView *)[self performSelector: @selector(containerView)];

                CGRect frame = containerView.frame;
                frame.origin.y = 20;
                frame.size.height = screen.size.height - 20;
                containerView.frame = frame;
            } else {
                CGRect frame = self.view.frame;
                frame.origin.y = 20;
                frame.size.height = screen.size.height - 20;
                self.view.frame = frame;
            }
        }
    }
}

4 Thêm điều này để làm cho thanh trạng thái của bạn có màu trắng Ngay sau [self.window makeKeyAndVosystem]; !!!

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}

nhưng điều này không hiển thị thời gian ở phía trên ... bất lợi lớn nhất ... :(
Fahim Parkar

Hoạt động tốt, nhưng đối với bước 4, bạn nên sử dụng PriorityStatusBarStyle trong bộ điều khiển chế độ xem của mình, vì setStatusBarStyle không được dùng nữa và hành động mặc định là không làm gì cả. stackoverflow.com/a/19014724/1192732
CpnCrunch

13
-(UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

-(void)viewWillLayoutSubviews{

 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
  {
    self.view.clipsToBounds = YES;
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenHeight = 0.0;
    if(UIDeviceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
        screenHeight = screenRect.size.height;
    else
        screenHeight = screenRect.size.width;
    CGRect screenFrame = CGRectMake(0, 20, self.view.frame.size.width,screenHeight-20);
    CGRect viewFrame1 = [self.view convertRect:self.view.frame toView:nil];
    if (!CGRectEqualToRect(screenFrame, viewFrame1))
    {
        self.view.frame = screenFrame;
        self.view.bounds = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    }
  }
}

Thêm Key trong plist --- Xem giao diện thanh trạng thái dựa trên bộ điều khiển: KHÔNG


thay đổi cửa sổ màu nếu cần
Darshit Shah

Cảm ơn, Nó đã giải quyết vấn đề chồng chéo của tôi. Nhưng một vấn đề vẫn còn đó - Xem giao diện thanh trạng thái dựa trên bộ điều khiển: KHÔNG là ẩn thanh trạng thái, tôi đoán. Nhưng khi tôi đặt nó thành CÓ, thì nó không hiển thị thanh trạng thái và khi tôi đặt nó thành KHÔNG thì nó hiển thị thanh trạng thái. Vì vậy, xin vui lòng cho tôi biết tôi có sai với khái niệm hay những gì?
Nayan

1
Tôi nghĩ là vì đặt màu bán chuyển tiếp mặc định trong didFinishLaunchingWithOptions 'self.window.backgroundColor = [UIColor blueColor];' và thiết lập trong plist Xem điều khiển dựa trên thanh trạng thái xuất hiện YES
Darshit Shah

Cảm ơn rất nhiều! Ngoài ra, chỉ để chỉ ra rằng các tài liệu của apple khuyên bạn nên kiểm tra với if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1) {} else {}. Chúc mừng!
Joel Balmer

Cảm ơn bạn rất nhiều. Mã của bạn rất hữu ích cho chúng tôi. Vui lòng giải thích về chức năng viewWillLayoutSubviews.
user3182143 23/02/16

4

Để ẩn thanh trạng thái trong ios7, hãy làm theo các bước đơn giản sau:

Trong Resourcesthư mục Xcode goto " " và mở " (app name)-Info.plist file".

  • kiểm tra View controller based status bar appearancekhóa "" và đặt giá trị của nó " NO"
  • kiểm tra Status bar is initially hiddenkhóa "" và đặt giá trị của nó " YES"

Nếu các phím không có ở đó thì bạn có thể thêm nó bằng cách chọn " information property list" ở trên cùng và nhấp vào + biểu tượng


Đọc câu hỏi rõ ràng, Anh không yêu cầu ẩn hoàn toàn thanh trạng thái.
ShayanK

1
@AspersionCast: Anh ấy hỏi "Có cách nào để tránh điều này không?" và đây là một trong những cách để tránh nó.
Mandeep Pasbola


3

Nếu sử dụng xibs, cách triển khai rất dễ dàng là đóng gói tất cả các chế độ xem phụ bên trong chế độ xem vùng chứa với các cờ thay đổi kích thước (bạn sẽ sử dụng cờ này cho khả năng tương thích 3,5 "và 4") để cấu trúc phân cấp chế độ xem trông giống như thế này

xib heirarchy

và sau đó viewDidLoad, làm một cái gì đó như sau:

- (void)viewDidLoad
{
  [super viewDidLoad];
  // initializations
  if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) // only for iOS 7 and above
  {
    CGRect frame = containerView.frame;
    frame.origin.y += 20;
    frame.size.height -= 20;
    containerView.frame = frame;
  }
}

Bằng cách này, các ngòi không cần phải sửa đổi để tương thích với iOS 7. Nếu bạn có nền, nó có thể được giữ bên ngoài containerViewvà để nó bao phủ toàn bộ màn hình.


3

Đây là tất cả những gì cần thiết để xóa thanh trạng thái. nhập mô tả hình ảnh ở đây


2

Đối với Thanh điều hướng:

Viết mã này:

self.navigationController.navigationBar.translucent = NO;

vừa làm thủ thuật cho tôi.


1

Câu trả lời của Vincent edgeForExtendedLayout đã làm việc cho tôi.

Các macro này giúp xác định phiên bản hệ điều hành dễ dàng hơn

// 7.0 and above 
#define IS_DEVICE_RUNNING_IOS_7_AND_ABOVE() ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) 

// 6.0, 6.0.x, 6.1, 6.1.x
#define IS_DEVICE_RUNNING_IOS_6_OR_BELOW() ([[[UIDevice currentDevice] systemVersion] compare:@"6.2" options:NSNumericSearch] != NSOrderedDescending) 

thêm các macro này vào tệp prefix.pch của dự án của bạn và có thể được truy cập ở mọi nơi

if(IS_DEVICE_RUNNING_IOS_7_AND_ABOVE())
{
 //some iOS 7 stuff
 self.edgesForExtendedLayout = UIRectEdgeNone;
}

if(IS_DEVICE_RUNNING_IOS_6_OR_BELOW())
{
 // some old iOS stuff
}

1
cho tôi self.edgesForExtendedLayout = UIRectEdgeNone; không hoạt động ... bất kỳ lý do tại sao?
Fahim Parkar

1

Tôi đã đăng câu trả lời của mình cho một bài đăng khác có cùng câu hỏi với bài này.

Từ Hướng dẫn chuyển đổi iOS7 của Apple, https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/AppearanceCustomization.html#//apple_ref/doc/uid/TP40013174-CH15-SW1

Cụ thể automaticallyAdjustsScrollViewInsets=YESset self.edgesForExtendedLayout = UIRectEdgeNonelàm việc cho tôi khi tôi không muốn chồng chéo và tôi có tableviewcontroller.


0

Nếu bạn muốn bật "Sử dụng Tự động thanh toán" bằng mọi giá, hãy đặt mã sau vào viewdidload.

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
{
        self.edgesForExtendedLayout = UIRectEdgeNone;
        self.extendedLayoutIncludesOpaqueBars = NO;
        self.automaticallyAdjustsScrollViewInsets = NO;
}

0

Thanh trạng thái và thanh điều hướng của tôi chồng lên nhau sau khi quay lại từ chế độ xem ngang của YTPlayer. Đây là giải pháp của tôi sau khi thử phiên bản @comonitos 'nhưng không hoạt động trên iOS 8 của tôi

- (void)fixNavigationBarPosition {
    if (self.navigationController) {
        CGRect frame = self.navigationController.navigationBar.frame;
        if (frame.origin.y != 20.f) {
            frame.origin.y = 20.f;
            self.navigationController.navigationBar.frame = frame;
        }
    }
}

Chỉ cần gọi chức năng này bất cứ khi nào bạn muốn cố định vị trí của thanh điều hướng. Tôi đã gọi trên YTPlayerViewDelegate'splayerView:didChangeToState:

- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state {
    switch (state) {
        case kYTPlayerStatePaused:
        case kYTPlayerStateEnded:
            [self fixNavigationBarPosition];
            break;
        default:
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.