2012年10月13日 星期六

iOS6 UI rotation issue

Apple does teach me a lesson that I should read the release note first!

If the app is navigation based, you may want to read this:
每個viewcontroller可支援的方向都能彈性調整 ,主要就是參照top-most viewcontroller (root viewcontroller)裡的設定

  • Autorotation is changing in iOS 6. In iOS 6, the shouldAutorotateToInterfaceOrientation: method of UIViewController is deprecated. In its place, you should use the supportedInterfaceOrientationsForWindow: and shouldAutorotate methods.
    簡單來說,
     shouldAutorotateToInterfaceOrientation在iOS6失效了,請改用supportedInterfaceOrientationsForWindow: 跟 shouldAutorotate:
    • More responsibility is moving to the app and the app delegate. Now, iOS containers (such as UINavigationController) do not consult their children to determine whether they should autorotate. By default, an app and a view controller’s supported interface orientations are set to UIInterfaceOrientationMaskAll for the iPad idiom and UIInterfaceOrientationMaskAllButUpsideDown for the iPhone idiom.
      控制方向旋轉的功能被提升到delegate來作管控,以往什麼self.navigationcontroller 沒辦法一招吃天下啦; 然後iPhone預設不支援頭上腳下的方向,iPad預設則是通通支援.
    • A view controller’s supported interface orientations can change over time—even an app’s supported interface orientations can change over time. The system asks the top-most full-screen view controller (typically the root view controller) for its supported interface orientations whenever the device rotates or whenever a view controller is presented with the full-screen modal presentation style. Moreover, the supported orientations are retrieved only if this view controller returns YES from its shouldAutorotate method. The system intersects the view controller’s supported orientations with the app’s supported orientations (as determined by the Info.plist file or the app delegate’s application:supportedInterfaceOrientationsForWindow: method) to determine whether to rotate.
      iOS6的autorotate方法是給top most view controller來做控管,可以在app delegate裡面透過application:supportedInterfaceOrientationsForWindow:來設定,或是寫在plist裡面;總之支援的方向可以隨時改變甚至是present view都沒問題,只要確定shouldAutorotate的回傳值是YES就對了.
    • The system determines whether an orientation is supported by intersecting the value returned by the app’s supportedInterfaceOrientationsForWindow: method with the value returned by the supportedInterfaceOrientations method of the top-most full-screen controller.
      系統決定app 支援哪些方向是取決於兩個method的交集: supportedInterfaceOrientationsForWindow:跟supportedInterfaceOrientations
    • The setStatusBarOrientation:animated: method is not deprecated outright. However, it now works only if the supportedInterfaceOrientations method of the top-most full-screen view controller returns 0. This puts the responsibility of ensuring that the status bar orientation is consistent into the hands of the caller.
      現在setStatusBarOrientation:animated:是由top-most view controller 來控制, 另外一個條件就是supportedInterfaceOrientations回傳值為0,這樣纔會work.
    • For compatibility, view controllers that still implement the shouldAutorotateToInterfaceOrientation: method do not get the new autorotation behaviors. (In other words, they do not fall back to using the app, app delegate, or Info.plist file to determine the supported orientations.) Instead, the shouldAutorotateToInterfaceOrientation: method is used to synthesize the information that would be returned by the supportedInterfaceOrientations method.
      由於兼容性的關係,所以一旦實作了shouldAutorotateToInterfaceOrientation:這個方法,那app就不會去管delegate或是plist裡面關於autorotation的設定;shouldAutorotateToInterfaceOrientation:這個方法可以視作為supportedInterfaceOrientations的getter&setter function
  • The willRotateToInterfaceOrientation:duration:willAnimateRotationToInterfaceOrientation:duration:, and didRotateFromInterfaceOrientation: methods are no longer called on any view controller that makes a full-screen presentation over itself—for example, by calling presentViewController:animated:completion:.
    這裡提到willRotateToInterfaceOrientation:duration:willAnimateRotationToInterfaceOrientation:duration:didRotateFromInterfaceOrientation:這三個function都不會再有event觸發,所以當present一個viewcontroller之後不能依靠這三個function來更新或是調整layout而是該改用下面的這個viewWillLayoutSubviews
    • You should make sure that your apps are not using these methods to manage the layout of any subviews. Instead, they should use the view controller’s viewWillLayoutSubviews method and adjust the layout using the view’s bounds rectangle.

前面廢話完了,回歸正題
如果app需要用到navigation controller的話:
1. 先check app delegate

1
2
urNavigationCtrl = [[UINavigationController alloc] initWithRootViewController:viewController];
[window addSubview:urNavigationCtrl.view];

改成

1
2
3
urNavigationCtrl = [[UINavigationController alloc] init];
[urNavigationCtrl pushViewController:firstViewCtrl animated:NO];
self.window.rootViewController = urNavigationCtrl;

2. 參照aprato在stackoverflow的解答, 我們需要Category來解決使用加了navigation controller之後的後遺症.在第一個view的.m裡面加上這段code


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
@implementation UINavigationController (Rotation_IOS6)

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}

@end

3. 然後在每一個需要overwrite的頁面重新define自己想要的行為, for example:

1
2
3
4
5
6
7
- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

資料來源:9to5macdisanji.netroostersoftstudios


2012年10月1日 星期一

MJPEG Streaming Issue on iOS6

Well done Apple, I got many complains from users that their app will crash after upgrade to iOS6.

After I checked the log, there are all error messages from CFNetwork.
Seems the internal error will lead to run out of memory!

CFNetwork internal error (0xc01a:/SourceCache/CFNetwork_Sim/CFNetwork-609/Connection/URLConnectionClient.cpp:1145)

What's more, only particular ip camera will have this issue....@#$%
Can't wait to console worldwide users, that I am using workaround:

Due to mjpeg stream is consist of continuous jpeg images.
Thus I using snapshot cgi rather than mjpeg stream cgi.

Will keep digging the root cause, and will update if have any news~ sigh

update:2012/10/05
Seems the boundary format is invalid!
Because the vendor defines boundary=--video boundary-- in the header
But comes out --video boundary--
It should be ----video boundary--

Here is the wiki definition of MIME multipart message

update:2012/10/13
Fix the boundary format issue, but still have the same problem >"<
Back to the origin...

update:2012/10/18

Bingo! We got a new f/w and fix another format issue~
The CFNetwork error never happen anymore, but I believe there are still other traps will cause the error! The fault tolerance of CFNetwork is too weak!!


Right Format






















Wrong Format

內容回應