0

it's all start from a lot of warnings about the width of collectionView cells, That was written to console every time I press home button.

I thought it's something with size of the cells and tried to fix it. Only after some testing, I notice that viewDidLayoutView is called with wrong view.bounds, and that make the collectionView cell bigger(in width) than collection view.

For now, my fix is to check if app is on background state and ignore viewDidLayoutView.

  1. why it's happen only in iPad and not on iPhone ?
  2. it's whirred that only now I saw this happening. it's something new in iOS ?
  3. what is the right way to handle this ? I don't use auto-layout
  4. its calling with wrong bounds and I don't want to calculate all cells frames just for the user to return to the same orientation.
  5. I feel like I'm missing something very basic here OR there is some change on iOS that I'm not aware.
user1105951
  • 2,259
  • 2
  • 34
  • 55
  • The reason that happens on iPad is because the app is rotated in order to take screenshots for the App Switcher in both orientations. What's your question? – matt Jul 09 '19 at 17:04
  • I edit the title. I'm not calling viewDidLayoutSubview, iOS call it when I press home button and move app to background – user1105951 Jul 09 '19 at 17:05
  • But what's the _question_? I've told you why `viewDidLayoutSubviews` is called. Do you have a problem with that? If so, what is the problem? – matt Jul 09 '19 at 17:08
  • Is there a chat I can explain ? – user1105951 Jul 09 '19 at 17:09
  • Edit the question so that it becomes a valid question. Right now, all you have is "Is this the right behaviour?" And I've told you, yes it is, and I've explained why. What more do you want? – matt Jul 09 '19 at 17:12
  • ok. I will right everything. but please be patience, I understand you are trying to help, but sometimes the hardest/ whirred problems, are hard to explain cause maybe I missing something very basic or there IS real problem here. 2 minutes I will write everything. – user1105951 Jul 09 '19 at 17:14

1 Answers1

5

why it's happen only in iPad and not on iPhone ?

Because when you click Home on an iPad and the app goes into the background, the runtime takes two snapshots, one in each orientation, to use in the App Switcher interface (and in preparation for when the app comes back to the front). That means it has to rotate the app, which triggers layout, and so your viewDidLayoutSubviews is called.

it's whirred that only now I saw this happening. it's something new in iOS ? what is the right way to handle this ? I don't use auto-layout its calling with wrong bounds and I don't want to calculate all cells frames just for the user to return to the same orientation. I feed like I'm missing something very basic here OR there is some change on iOS that I'm not aware.

Well, iPads have been behaving like this for quite a long time. It isn't my job to explain why you haven't noticed. Basically you should not be doing anything time-consuming in viewDidLayoutSubviews.

for now, my fix is to check if app is on background state and ignore viewDidLayoutView

That's perfectly reasonable. I do the same sort of thing. For example (this is a different method, but it's the same idea):

override func viewWillTransition(to size: CGSize, with tc: UIViewControllerTransitionCoordinator) {
    if UIApplication.shared.applicationState == .background {
        return
    }
    // ...
}

Be warned, however, that if you are doing manual layout and you don't do it when the app when goes into the background, your App Switcher snapshots may look wrong. Also, the fact that you are not using autolayout is a red flag. You should probably use it.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • You have not said _what_ you are doing in `viewDidLayoutSubviews` or _what_ warnings you are getting, so that's all I can tell you based on what you _did_ say. – matt Jul 09 '19 at 17:38
  • in viewDidLayoutSubview I just set frame of view bounds to collectionView. but because it's has portrait bounds while iPad (and collection view cells ) are on landscape, the width of the cell are bigger the collection view, this send a lot of warnings that I need to correct the layout of cells. – user1105951 Jul 09 '19 at 17:40
  • Why on iPad it take 2 snapshot and not also on iPhone ? – user1105951 Jul 09 '19 at 17:44
  • Because that is what Apple has decided it should do. – matt Jul 09 '19 at 17:44
  • "but because it's has portrait bounds while iPad (and collection view cells ) are on landscape, the width of the cell are bigger the collection view, this send a lot of warnings that I need to correct the layout of cells" No, the app is rotated twice. When it's in landscape, it's in landscape, and you should lay out for landscape. When it's in portrait, it's in portrait, and you should lay out for portrait. If you don't, your snapshots will be wrong. – matt Jul 09 '19 at 17:46
  • OK. thanks a lot for your help. I'm very surprised with this behaviour . about auto-layout, on complicated layout in cell (cell that serve different types) I prefer not using apple magic, but have FULL control. – user1105951 Jul 09 '19 at 17:47
  • yea. I understand that. but I'm not going to re-calcalute all entities frames just for that. I'm caching all frames layout, its can be 1000 entities and more. I will check how it look in app switcher. – user1105951 Jul 09 '19 at 17:48
  • Well, you should be calculating 1000 entities in `viewDidLayoutSubviews`. That is what I mean when I said "you should not be doing anything time-consuming". It sounds to me like your code has just been wrong all along, and now it is exposed. – matt Jul 09 '19 at 17:54
  • I calculate layouts on 2 cases : 1. first loading. 2. rotation. maybe now I will add another case : 3. if app is on background, also re-calculate entities cached frames. at least now , thanks 2 u, I understand what's going on. thank you. – user1105951 Jul 09 '19 at 18:07
  • What's going to happen when the user puts your app into multitasking mode and splits the screen? Now your app will adopt some width you've never considered before. That's _another_ "case". – matt Jul 09 '19 at 18:24
  • I expect multatasking mode to trigger viewWillTransition like rotation, no ? – user1105951 Jul 09 '19 at 18:26
  • When testing this behaviour on other iOS app I developed, the viewDidLayoutSubviews called twice but with correct width/height (when moving app to background). this is the reason I was so surprise with the second app, cause it's the first time I saw "wrong" bound.size. what is the different between 2 apps ? – user1105951 Jul 09 '19 at 20:24
  • You have both apps. I don't have either of them. You tell _me_ what the difference is. – matt Jul 09 '19 at 21:18
  • @matt I did a test, `viewDidLayoutSubviews` is called in iPhone for iOS 14.2. – huahuahu Dec 24 '20 at 00:31