iOS 7 - แถบสถานะซ้อนทับมุมมอง


109

ฉันมีViewControllerที่อยู่ภายใน a UINavigationcontrollerแต่ navigationBar ซ่อนอยู่ เมื่อฉันเรียกใช้แอปบน iOS 7 แถบสถานะจะแสดงที่ด้านบนของมุมมองของฉัน มีวิธีหลีกเลี่ยงสิ่งนี้หรือไม่?

ฉันไม่ต้องการเขียนโค้ดเฉพาะของระบบปฏิบัติการใด ๆ

ใส่คำอธิบายภาพที่นี่

ฉันพยายามตั้งค่าView controller-based status bar appearanceเป็นNOแต่ก็ไม่สามารถแก้ไขปัญหาได้


ฉันได้โพสต์คำตอบเพื่อแสดงแถบสถานะเช่น iOS 6 ใน iOS 7 stackoverflow.com/questions/18294872/…
Desert Rose

2
คุณต้องปรับจุดเริ่มต้นของ y และค่าเดลต้าด้วยเพื่อจัดการกับปัญหาแถบสถานะสิ่งนี้อาจช่วยคุณได้ stackoverflow.com/q/18980925/1545180
Ganapathy

คำตอบ:


95

Xcode 5 มีiOS 6/7 Deltasขึ้นเพื่อแก้ไขปัญหานี้โดยเฉพาะ ในสตอรีบอร์ดฉันเลื่อนมุมมองลง 20 พิกเซลเพื่อให้ดูถูกต้องบน iOS 7 และเพื่อให้เข้ากันได้กับ iOS 6 ฉันจึงเปลี่ยนDelta yเป็น -20

ใส่คำอธิบายภาพที่นี่

เนื่องจากสตอรีบอร์ดของฉันไม่ได้ใช้การจัดวางอัตโนมัติเพื่อที่จะปรับขนาดความสูงของมุมมองอย่างถูกต้องบน iOS 6 ฉันจึงต้องตั้งค่าDelta heightเช่นเดียวกับDelta Y.


8
คำตอบของคุณถูกต้อง แต่ใช้ไม่ได้กับจอแสดงผล 4 "โปรดอัปเดตคำตอบของคุณหากคุณสามารถทำให้ใช้งานได้สำหรับจอแสดงผล 4" ด้วย ขอบคุณล่วงหน้า.

2
@AnkitMehta ฉันไม่ต้องทำอะไรเฉพาะสำหรับ
iPhone

5
ทำงานให้ฉัน โปรดสังเกตว่าในการดูเดลต้านี้คุณต้องยกเลิกการเลือก 'ใช้การจัดวางอัตโนมัติ' ภายใต้ 'เอกลักษณ์และประเภท' สำหรับสตอรีบอร์ด
marsant

2
ฉันพบว่านอกจากการตั้งค่า -20 สำหรับ ∆Y แล้วฉันยังต้องตั้งค่า +20 เป็น ∆Height
Toland Hon

3
จะเกิดอะไรขึ้นเมื่อความสูงของแถบสถานะเปลี่ยนไป F.ex: เมื่อผู้ใช้เปิดใช้งานฮอตสปอต ฯลฯ .... แล้วความสูงคือ 40px ...
Lukasz

69

หากคุณไม่ต้องการแถบสถานะใด ๆ เลยคุณต้องอัปเดต plist ของคุณด้วยข้อมูลนี้: ในการดำเนินการนี้ให้เพิ่มการตั้งค่า 2 รายการใน plist:

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

ใน iOS 7 คุณคาดว่าจะออกแบบแอปโดยคำนึงถึงแถบสถานะโปร่งใสที่ซ้อนทับอยู่ ดูตัวอย่างแอป iOS 7 Weather ใหม่


3
นี่เป็นคำตอบที่ดีเพียงคำตอบเดียวเนื่องจากจะแก้ไขปัญหาที่แกนหลักตามวิธีที่ควรทำ ดังนั้น: จำเป็นต้องมีการโหวตเพิ่ม!
eleven59

5
อาจเหมาะสมสำหรับบางสถานการณ์ แต่คุณต้องระมัดระวังในการซ่อนแถบสถานะ สำหรับมุมมองที่เป็นแบบเต็มหน้าจอเท่านั้นเช่นโปรแกรมเล่นสื่อหรือโปรแกรมดูภาพ
smileBot

1
@ eleven59 คุณหมายถึงวิธีที่ผู้มีอำนาจใน Apple ตั้งใจ
JohnK

1
แบบนี้ดีกว่าการเปลี่ยนออฟเซ็ตของ view controller (ซึ่งรู้สึกสกปรกจริงๆ)
Benjamin Oman

การซ่อนแถบสถานะไม่ใช่ความคิดที่ดี ... ฉันรู้ว่านี่เป็นวิธีที่ง่ายที่สุดในการจัดการ iOS 7 แต่จำเป็นต้องมีเวลา ...
Fahim Parkar

43

นี่เป็นลักษณะการทำงานเริ่มต้นสำหรับUIViewControlleriOS 7 มุมมองจะเป็นแบบเต็มหน้าจอซึ่งหมายความว่าแถบสถานะจะครอบคลุมด้านบนของมุมมองของคุณ

หากคุณมีUIViewControllerภายใน a UINavigationControllerและ navigationBar มองเห็นได้คุณสามารถมีรหัสต่อไปนี้ในของคุณviewDidLoadหรือมีภาพพื้นหลังสำหรับ navigationBar ทำเคล็ดลับ

self.edgesForExtendedLayout = UIRectEdgeNone;

หากคุณมี navigationBar ซ่อนอยู่คุณจะต้องปรับองค์ประกอบ UIView ทั้งหมดโดยเลื่อน 20 จุด ฉันไม่เห็นวิธีแก้ปัญหาอื่นใด ใช้รูปแบบอัตโนมัติจะช่วยได้เล็กน้อย

นี่คือโค้ดตัวอย่างสำหรับการตรวจจับเวอร์ชัน iOS หากคุณต้องการใช้งานร่วมกันได้แบบย้อนหลัง

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
แทนที่จะดึงแยกวิเคราะห์และเปรียบเทียบเวอร์ชันของระบบขอแนะนำให้ใช้if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
Sebastian Hojas

15

โซลูชันที่ใช้งานได้เท่านั้นที่ฉันทำด้วยตัวเอง

นี่คือคลาสย่อย UIViewController ของฉันhttps://github.com/comonitos/ios7_overlaping

1 Subclass จาก UIViewController

2 ซับคลาส window.rootViewController ของคุณจากคลาสนั้น

3 โวลา!

- (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 เพิ่มสิ่งนี้เพื่อทำให้แถบสถานะของคุณเป็นสีขาวถัดจาก [self.window makeKeyAndVisible]; !!!

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

แต่นี่ไม่แสดงเวลาที่ด้านบน ... ข้อเสียที่ใหญ่ที่สุด ... :(
Fahim Parkar

ใช้งานได้ดี แต่สำหรับขั้นตอนที่ 4 คุณควรใช้ recommendedStatusBarStyle ในตัวควบคุมมุมมองของคุณเนื่องจาก setStatusBarStyle เลิกใช้งานแล้วและการกระทำเริ่มต้นคือการไม่ทำอะไรเลย 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);
    }
  }
}

เพิ่มคีย์ใน plist --- ดูลักษณะแถบสถานะตามคอนโทรลเลอร์: NO


เปลี่ยน
สีหน้าต่างหาก

ขอบคุณมันแก้ไขปัญหาที่ทับซ้อนกันของฉัน แต่ปัญหาหนึ่งยังคงมีอยู่ - ดูลักษณะแถบสถานะตามคอนโทรลเลอร์: ไม่คือการซ่อนแถบสถานะที่ฉันเดา แต่เมื่อฉันตั้งค่าเป็นใช่แถบสถานะจะไม่แสดงและเมื่อฉันตั้งค่าเป็นไม่ใช่แถบสถานะจะแสดง ดังนั้นโปรดบอกฉันว่าฉันผิดกับแนวคิดหรืออะไร
Nayan

1
ฉันคิดว่าเพราะใช้ชุดสีกึ่งโปร่งแสงเริ่มต้นใน didFinishLaunchingWithOptions 'self.window.backgroundColor = [UIColor blueColor];' และตั้งค่าในแถบสถานะตาม
คอนโทรลเลอร์ Plist View

ขอบคุณมาก! นอกจากนี้เพื่อชี้ให้เห็นว่า apple docs แนะนำให้ตรวจสอบด้วย if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1) {} else {} ไชโย!
Joel Balmer

ขอบคุณมากรหัสของคุณมีประโยชน์มากสำหรับเราโปรดอธิบายเกี่ยวกับฟังก์ชัน viewWillLayoutSubviews
user3182143

4

หากต้องการซ่อนแถบสถานะใน ios7 ให้ทำตามขั้นตอนง่ายๆเหล่านี้:

ในResourcesโฟลเดอร์Xcode goto " " และเปิด " (app name)-Info.plist file"

  • ตรวจสอบView controller based status bar appearanceคีย์ "" และตั้งค่า " NO"
  • ตรวจสอบStatus bar is initially hiddenคีย์ "" และตั้งค่า " YES"

หากไม่มีคีย์คุณสามารถเพิ่มได้โดยเลือก " information property list" ที่ด้านบนแล้วคลิกไอคอน+


อ่านคำถามให้ชัดเจนเขาไม่ได้ขอให้ซ่อนแถบสถานะทั้งหมด
ShayanK

1
@AspersionCast: เขาถามว่า "มีวิธีหลีกเลี่ยงสิ่งนี้หรือไม่" และนี่เป็นหนึ่งในวิธีหลีกเลี่ยง
Mandeep Pasbola


3

หากใช้xibs การใช้งานที่ง่ายมากคือการห่อหุ้มมุมมองย่อยทั้งหมดไว้ในมุมมองคอนเทนเนอร์ด้วยแฟล็กการปรับขนาด(ซึ่งคุณจะใช้สำหรับความเข้ากันได้ 3.5 "และ 4" อยู่แล้ว)เพื่อให้ลำดับชั้นของมุมมองมีลักษณะดังนี้

xib heirarchy

จากนั้นviewDidLoadทำสิ่งนี้:

- (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;
  }
}

วิธีนี้ไม่จำเป็นต้องปรับเปลี่ยนหัวปากกาเพื่อความเข้ากันได้กับ iOS 7 หากคุณมีพื้นหลังสามารถเก็บไว้ด้านนอกcontainerViewและปล่อยให้ครอบคลุมทั้งหน้าจอ



2

สำหรับแถบนำทาง:

การเขียนรหัสนี้:

self.navigationController.navigationBar.translucent = NO;

เพียงแค่ทำเคล็ดลับสำหรับฉัน


1

คำตอบของ Vincent edgeForExtendedLayout ใช้ได้ผลกับฉัน

มาโครเหล่านี้ช่วยในการกำหนดเวอร์ชันของระบบปฏิบัติการทำให้ง่ายขึ้น

// 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) 

เพิ่มมาโครเหล่านี้ลงในไฟล์ prefix.pch ของโครงการของคุณและสามารถเข้าถึงได้ทุกที่

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
สำหรับฉัน self.edgesForExtendedLayout = UIRectEdgeNone; ใช้งานไม่ได้ ... เพราะอะไร?
Fahim Parkar

1

ฉันได้โพสต์คำตอบของฉันไปยังโพสต์อื่นที่มีคำถามเดียวกันกับคำถามนี้

จากคู่มือการเปลี่ยน Apple iOS7 https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/AppearanceCustomization.html#//apple_ref/doc/uid/TP40013174-CH15-SW1

โดยเฉพาะautomaticallyAdjustsScrollViewInsets=YESและset self.edgesForExtendedLayout = UIRectEdgeNoneเหมาะสำหรับฉันเมื่อฉันไม่ต้องการทับซ้อนและฉันมีไฟล์tableviewcontroller.


0

หากคุณต้องการเปิดใช้งาน "ใช้การจัดวางอัตโนมัติ" โดยเสียค่าใช้จ่ายใด ๆ ให้ใส่รหัสต่อไปนี้ใน viewdidload

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

0

แถบสถานะและแถบการนำทางของฉันทับซ้อนกันหลังจากกลับจากมุมมองแนวนอนของ YTPlayer นี่คือวิธีแก้ปัญหาของฉันหลังจากลองใช้เวอร์ชันของ @comonitos แต่ใช้ไม่ได้กับ iOS 8

- (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;
        }
    }
}

เพียงเรียกใช้ฟังก์ชันนี้เมื่อใดก็ตามที่คุณต้องการแก้ไขตำแหน่งของแถบนำทาง ฉันเรียกใช้ YTPlayerViewDelegate'splayerView:didChangeToState:

- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state {
    switch (state) {
        case kYTPlayerStatePaused:
        case kYTPlayerStateEnded:
            [self fixNavigationBarPosition];
            break;
        default:
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.