简体   繁体   中英

How to fix strange behavior of date picker UIView when changing screen orientation in Objective-C?

I have this project that requires to change the screen orientation of application once the user will pick a date using datePicker . Once the user tapped the Date button, It will show the datePicker The first image is the correct layout of the datePicker when portrait mode.

Correct Portrait Layout正确的纵向布局

When changing the screen orientation from Landscape to Portrait . It will appear the issue. Please refer to image below.

The datePicker is located below 错误的横向布局

Which is the image below should be the correct layout once turned to landscape.

正确的横向布局

When you changed the screen orientation back to portrait. The datePicker layout changed. Please refer to image below.

Incorrect Portrait Layout

错误的纵向布局

Below are the codes used:

- (void)resizeView:(UIInterfaceOrientation)interfaceOrientation
{
//LOG(@"interfaceOrientation=%ld", (long)interfaceOrientation);
//LOG(@"self.frame =%@", NSStringFromCGRect(self.frame));
//LOG(@"self.bounds=%@", NSStringFromCGRect(self.bounds));

CGFloat x, y, w, h;
viewBack.frame = self.bounds;

#define _HEIGHT_LABEL   (40)
#define _HEIGHT_PICKER  (162)


#define _HEIGHT_TOOLBAR (CGRectGetHeight(toolBar.frame))//(44)
if (interfaceOrientation == UIInterfaceOrientationPortrait)
{
    LOG(@"[Portrait]");
    w = CGRectGetWidth(viewBack.frame);
    h = _HEIGHT_LABEL + _HEIGHT_PICKER*2 + _HEIGHT_TOOLBAR;
    viewPicker.frame = CGRectMake(0, 0, w, h);
    viewPicker.center = viewBack.center;

    x = 0;
    y = 0;
    w = CGRectGetWidth(viewPicker.frame);
    h = _HEIGHT_LABEL;
    lblTitle.frame = CGRectMake(x, y, w, h);

    x = 0;
    y = CGRectGetMaxY(lblTitle.frame);
    w = CGRectGetWidth(viewPicker.frame);
    h = _HEIGHT_PICKER;
    datePicker.frame = CGRectMake(x, y, w, h);

    x = 0;
    y = CGRectGetMaxY(datePicker.frame);
    w = CGRectGetWidth(viewPicker.frame);
    h = CGRectGetHeight(datePicker.frame); //datePickerと同じ
    timePicker.frame = CGRectMake(x, y, w, h);

    x = 0;
    y = CGRectGetMaxY(timePicker.frame);
    w = CGRectGetWidth(viewPicker.frame);
    h = _HEIGHT_TOOLBAR;
    toolBar.frame = CGRectMake(x, y, w, h);
    //LOG(@"tool  =%@", NSStringFromCGRect(toolBar.frame));
}
    else if (interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
    LOG(@"[Landscape]");
    w = CGRectGetWidth(viewBack.frame);
    h = _HEIGHT_LABEL + _HEIGHT_PICKER + _HEIGHT_TOOLBAR;
    viewPicker.frame = CGRectMake(0, 0, w, h);
    viewPicker.center = viewBack.center;

    x = 0;
    y = 0;
    w = CGRectGetWidth(viewPicker.frame);
    h = _HEIGHT_LABEL;
    lblTitle.frame = CGRectMake(x, y, w, h);

    w = CGRectGetWidth(viewPicker.frame) / 2; //画面幅の半分
    x = CGRectGetMidX(viewPicker.frame) - w;
    y = CGRectGetMaxY(lblTitle.frame);
    h = _HEIGHT_PICKER;
    datePicker.frame = CGRectMake(x, y, w, h);

    x = CGRectGetMidX(viewPicker.frame);
    y = CGRectGetMinY(datePicker.frame); //datePickerと同じ
    w = CGRectGetWidth(datePicker.frame); //datePickerと同じ
    h = CGRectGetHeight(datePicker.frame); //datePickerと同じ
    timePicker.frame = CGRectMake(x, y, w, h);

    x = 0;
    y = CGRectGetMaxY(datePicker.frame);
    w = CGRectGetWidth(viewPicker.frame);
    h = CGRectGetHeight(toolBar.frame);//44;
    toolBar.frame = CGRectMake(x, y, w, h);
}

 #if 0
LOG(@"back  =%@", NSStringFromCGRect(viewBack.frame));
LOG(@"base  =%@", NSStringFromCGRect(viewPicker.frame));
LOG(@"image =%@", NSStringFromCGRect(imageViewBlackGraBar.frame));
LOG(@"label =%@", NSStringFromCGRect(lblTitle.frame));
LOG(@"date  =%@", NSStringFromCGRect(datePicker.frame));
LOG(@"time  =%@", NSStringFromCGRect(timePicker.frame));
LOG(@"tool  =%@", NSStringFromCGRect(toolBar.frame));
LOG(@"");
 #endif
}

This is additional information I gathered during my investigation. Below is the .xib for portrait and landscape.

肖像 景观

Try calling [[self view] layoutIfNeeded]; in resizeView

or [[self view] setNeedsLayout]; when orientation occurs.

use setNeedsLayout if you are okay with the system to update it in the next upcoming update cycle use layoutIfNeeded if you want it to be updated immediately.

You should use UITextField instead of UILabel and just set date picker as textField's inputView .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM