Limitations on limiting the aspect ratio of iOS on iOS7, works on iOS8

In my application, I have UIView constraints set so that its height is calculated by its width using the aspect ratio constraint. It works great on iOS8 with every device screen size (3.5, 4, 4.7, 5.5), but this leads to a crash of the application on every iOS7 device.

I assume that this is a restriction on the format, because if I replace it with a fixed height restriction, it no longer crashes (obviously, it looks bad on some devices).

The stack trace is extremely long, so I only copy parts of it.

Thank you in advance for your help!

Objective: {objective 0x7f9d90da33c0: <750:4692, 251:2936, 250:367> + <251:-1>*0x7f9d90c06220.marker{id: 592} + <251:-1>*0x7f9d90c24420.marker{id: 599} + <251:-1>*0x7f9d90c25650.marker{id: 594} + <251:-1>*0x7f9d90c27ad0.marker{id: 597} + <750:-1>*0x7f9d90c3b270.marker{id: 483} + <250:-3.9875>*0x7f9d90c43e40.marker{id: 618} + <250:-3.9875>*0x7f9d90c43e90.marker{id: 620} + <750:-4>*0x7f9d90c442e0.marker{id: 479} + <251:1>*0x7f9d90c464b0.marker{id: 485} + <251:-1>*0x7f9d90c46bf0.marker{id: 504} + <251:-1>*0x7f9d90c46c90.marker{id: 508} + <251:-1>*0x7f9d90c46ce0.marker{id: 510} + <251:-1>*0x7f9d90c46d80.marker{id: 514} + <251:-2>*0x7f9d90c4aa60.marker{id: 623} + <251:-2>*0x7f9d90c4aab0.marker{id: 625} + <251:-2, 250:-3.9875>*0x7f9d90c4ab50.marker{id: 631} + <251:-2, 250:-3.9875>*0x7f9d90c4abf0.marker{id: 634} + <251:4, 250:3.9875>*0x7f9d90c4ac40.marker{id: 637} + <251:4, 250:3.9875>*0x7f9d90c4ac90.marker{id: 642} + <750:1, 251:1>*0x7f9d90c4c530.negError{id: 645} + <750:1, 251:1>*0x7f9d90c4cb20.posErrorMarker{id: 646} + <750:1, 251:1>*0x7f9d90c530f0.negError{id: 649} + <750:1, 251:1>*0x7f9d90c53150.negError{id: 651} + <750:1, 250:1>*0x7f9d90c53820.posErrorMarker{id: 652} + <750:1, 250:1>*0x7f9d90c538a0.posErrorMarker{id: 654} + <750:1, 250:1>*0x7f9d90c53fd0.posErrorMarker{id: 656} + <750:1, 250:1>*0x7f9d90c54070.posErrorMarker{id: 658} + <750:1, 251:1>*0x7f9d90c54650.negError{id: 661} + <750:1>*0x7f9d90c546b0.negError{id: 663} + <251:1>*0x7f9d90c546b0.posErrorMarker{id: 662} + <750:1>*0x7f9d90c55230.negError{id: 665} + <251:1>*0x7f9d90c55230.posErrorMarker{id: 664} + <750:1, 251:1>*0x7f9d90c552b0.negError{id: 667} + <750:1, 251:1>*0x7f9d90d34300.posErrorMarker{id: 916} + <750:1>*0x7f9d90de48a0.marker{id: 738} + <250:-1>*0x7f9d90de48f0.marker{id: 740} + <250:-1>*0x7f9d90de4940.marker{id: 744} + <750:1>*0x7f9d90de4990.marker{id: 745} + <750:1>*0x7f9d90de4c70.marker{id: 718} + <750:1>*0x7f9d90de4cc0.marker{id: 720} + <250:-1 

...

  Integralization Adjustments: 0x7f9d93042a90.marker{id: 532} [<NSLayoutConstraint:0x7f9d93042a90 UIView:0x7f9d9303d590.width == 1.50943*UIView:0x7f9d9303d590.height>] -> 0.132066 0x7f9d93042c70.marker{id: 546} [<NSLayoutConstraint:0x7f9d93042c70 UIButton:0x7f9d90de27a0.height == UIButton:0x7f9d93018ab0.height>] -> 1.000000 0x7f9d93042d60.marker{id: 552} [<NSLayoutConstraint:0x7f9d93042d60 UIButton:0x7f9d9303dbf0.width == UIButton:0x7f9d93018ab0.width>] -> -1.000000 0x7f9d93042db0.marker{id: 554} [<NSLayoutConstraint:0x7f9d93042db0 UIButton:0x7f9d9303dbf0.height == UIButton:0x7f9d93033b40.height>] -> 1.000000 0x7f9d93042ea0.marker{id: 562} [<NSLayoutConstraint:0x7f9d93042ea0 UIButton:0x7f9d93033b40.width == UIButton:0x7f9d9303c500.width>] -> -1.000000 0x7f9d930431c0.marker{id: 581} [<NSLayoutConstraint:0x7f9d930431c0 UIButton:0x7f9d9303c500.height == UIButton:0x7f9d93045880.height>] -> 1.000000 Statistics: 195 rows. Variable counts: 1 -> 59 2 -> 28 3 -> 3 4 -> 7 5 -> 4 6 -> 3 7 -> 3 8 -> 4 9 -> 8 10 -> 10 11 -> 11 12 -> 10 13 -> 7 14 -> 2 15 -> 3 16 -> 10 17 -> 17 18 -> 6 }: internal error. Cannot find an outgoing row head for incoming head UIView:0x7f9d930332a0.Height{id: 981}, which should never happen.' *** First throw call stack: ( 0 CoreFoundation 0x000000011284d495 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x000000011220699e objc_exception_throw + 43 2 CoreFoundation 0x000000011284d2ad +[NSException raise:format:] + 205 3 Foundation 0x0000000110dfb054 -[NSISEngine minimizeConstantInObjectiveRowWithHead:] + 178 4 Foundation 0x0000000110dfaf22 -[NSISEngine optimize] + 147 5 Foundation 0x0000000110f432e3 -[NSISEngine withBehaviors:performModifications:] + 192 6 UIKit 0x000000011126f889 -[UIView(Hierarchy) _postMovedFromSuperview:] + 321 7 UIKit 0x000000011126df42 __UIViewWasRemovedFromSuperview + 206 8 UIKit 0x000000011126db9e -[UIView(Hierarchy) removeFromSuperview] + 218 9 UIKit 0x0000000111330069 -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:] + 320 10 UIKit 0x0000000111328fdd __49-[UINavigationController _startCustomTransition:]_block_invoke + 138 11 UIKit 0x000000011187ec2a -[_UIViewControllerTransitionContext completeTransition:] + 78 12 UIKit 0x0000000111211da4 __53-[_UINavigationParallaxTransition animateTransition:]_block_invoke103 + 605 13 UIKit 0x00000001112746e8 -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 299 14 UIKit 0x000000011126068e -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 235 15 UIKit 0x0000000111260941 -[UIViewAnimationState animationDidStop:finished:] + 78 16 UIKit 0x000000011ef6d4b7 -[UIViewAnimationStateAccessibility(SafeCategory) animationDidStop:finished:] + 48 17 QuartzCore 0x0000000110ac9134 _ZN2CA5Layer23run_animation_callbacksEPv + 310 18 libdispatch.dylib 0x000000011327772d _dispatch_client_callout + 8 19 libdispatch.dylib 0x00000001132673fc _dispatch_main_queue_callback_4CF + 354 20 CoreFoundation 0x00000001128ab289 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 21 CoreFoundation 0x00000001127f8854 __CFRunLoopRun + 1764 22 CoreFoundation 0x00000001127f7d83 CFRunLoopRunSpecific + 467 23 GraphicsServices 0x0000000114223f04 GSEventRunModal + 161 24 UIKit 0x000000011121be33 UIApplicationMain + 1010 25 Playchat 0x000000010fa89513 main + 115 26 libdyld.dylib 0x00000001134fa5c9 start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException 
+6
source share
6 answers

This is one of the unpleasant mistakes that cost me many hours. I had the same problem, the application worked fine in iOS 8, but crashed on iOS 7.1. The problem was limiting the aspect ratio in the scroll. After you tried many different things, it finally solved the problem:

The failure appears to be the result of a floating-point calculation that is not executing at some point. In my case, I determined the aspect ratio of 16: 9, or rather, 9:16, which is 0.5625. Changing the multiplier from 0.5625 to 0.5624 fixed the problem , since then no more failures have appeared.

+10
source

I solved it as follows:

Suppose my panel looks the same on the iPhone 4, 4s, 5, 5s, as they have the same width, so their aspect ratio will result in the same height. I added a height constraint to the same view in which I added a aspect ratio constraint. Therefore, regardless of the version of iOS, on these devices, the view will look with height restrictions.

iPhone6 ​​and 6+ only run on iOS8 or higher, where the aspect ratio limit is not interrupted, I just remove the height limit if the iOS version is 8 or higher, otherwise I will remove the aspect ratio limit.

This is far from elegant, but solves the problem in a simple way.

+1
source

I ran into this crash on iOS7 when I had a combination of aspect ratios, equal height for the container and zero top and bottom distance to the container restrictions. The restriction on equal height of the container was excessive, because it was limited on top and bottom of the container, so I deleted it and stopped. This must be a bug in the OS.

0
source

Indeed, it should be an OS error ( iOS 7 ). I spent several days debugging the automatic merge completely (note: there are no NSLayout exceptions). I also collapsed.

This was ALL due to the use of some combination of constraints along with aspect ratio constraints.

I solve this with a change in the user interface ... Pain.

0
source

I have this problem with NSLayoutConstraint and the multiplier on iOS 7. Works great on iOS 8.

I use a factor of 0.2 and cause errors!

 NSLayoutConstraint(item: BT_Facebook, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: nil, attribute: .Width, multiplier: 0.2, constant: sizeBtRedeSociais) 

The solution is to use screen size rather than percentages.

 var sizeBtRedeSociais = UIScreen.mainScreen().bounds.width / 5 var BT_FacebookWidth = NSLayoutConstraint(item: BT_Facebook, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: nil, attribute: .Width, multiplier: 1, constant: sizeBtRedeSociais) var BT_TwitterWidth = NSLayoutConstraint(item: BT_Twitter, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: nil, attribute: .Width, multiplier: 1, constant: sizeBtRedeSociais) var BT_InstagramWidth = NSLayoutConstraint(item: BT_Instagram, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: nil, attribute: .Width, multiplier: 1, constant: sizeBtRedeSociais) var BT_GoogleWidth = NSLayoutConstraint(item: BT_Google, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: nil, attribute: .Width, multiplier: 1, constant: sizeBtRedeSociais) var BT_YoutubeWidth = NSLayoutConstraint(item: BT_Youtube, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: nil, attribute: .Width, multiplier: 1, constant: sizeBtRedeSociais) 
0
source

I decided that you are not establishing an attitude. You should set it equal with its container. But better you should set a height limit following the iPhone 6. You should turn off the limit in your class. In viewDidLoad you should multiply by DISPLAY_SCALE

  DISPLAY_SCALE = UIScreen.mainScreen().bounds.width / 375 

// 375 is the width of the iPhone 6.

Why would you do this? I think the delay is iOS7 when calculating our limit. And this is wrong when showing

0
source

Source: https://habr.com/ru/post/981449/


All Articles