SwiftKickMobile / SwiftMessages

A very flexible message bar for UIKit and SwiftUI.
MIT License
7.24k stars 742 forks source link

SwiftMessagesSegue crashes due to memory exhaustion on devices with notch (iPhone 11 and up) #441

Open kenosan opened 3 years ago

kenosan commented 3 years ago

This is a peculiar issue on iPhone devices/simulators. No problems on iPad variants.

Observation: Using SwiftMessagesSegue.configure(layout:) with .bottomTab causes an app crash as the app consumes memory until it is terminated by the system. From a user perspective the result is that the ViewController being presented by the segue does not show and the UI is frozen as the memory leak is occurring.

Code: I used the SwiftMessagesSegue to launch the ViewController with the following code:

let segue = SwiftMessagesSegue(identifier: nil, source: self, destination: targetViewController)
segue.configure(layout: .bottomTab)
segue.perform()

Crash occurs on the call to configure(layout:) specifically when using .bottomTab. Oddly, other bottom layout sseems to work. I was able to trace it to TopBottomAnimation.swift:100. Could not get past the call to container.layoutIfNeeded().

For now, I'm using configure(layout: .bottomCard) to make progress with my work but figured this should be reported. This only seems to happen on iPhone devices/simulators that do not have a physical home button.

Using SwiftMessages v8.0.3 via SPM

wtmoose commented 3 years ago

I haven't heard anyone else having this problem and I can't reproduce it. Here's my test project and screenshot running on an iPhone 12 device.

Could you try cleaning your workspace? If the problem persists, I'll need you to provide concrete reproduction steps, preferably in the form of a test project.

SwiftMessagesTest.zip

IMG_0062

kenosan commented 3 years ago

I've attached an extension of your code sample that shows the issue using a ViewController defined in the storyboard which is my use case.

Changes to sample code:

SwiftMessagesTest-MemBlowUp.zip

wtmoose commented 3 years ago

Sorry, somehow I missed your response. I've never seen anything like this. Something about your specific layout breaks Auto Layout. My guess is the stack view – they've historically not been very robust.

I don't have a solution yet, but I have a workaround.

segue.configure(layout: .bottomTab)
segue.messageView.bounceAnimationOffset = 1
segue.containment = .content
segue.containerView.cornerRadius = 0
segue.containerView.roundsLeadingCorners = false
segue.messageView.configureDropShadow()
segue.containment = .backgroundVertical
segue.messageView.layoutMarginAdditions = UIEdgeInsets(top: 20, left: 10, bottom: 20, right: 10)
segue.messageView.collapseLayoutMarginAdditions = true
segue.containerView.cornerRadius = 15
segue.containerView.roundsLeadingCorners = true
let animation = TopBottomAnimation(style: .bottom)
animation.springDamping = 1
segue.presentationStyle = .custom(animator: animation)

It is equivalent, except I've changed:

messageView.bounceAnimationOffset = 0

to

messageView.bounceAnimationOffset = 1

Which is a negligible difference. Hope that helps.

tylerjames commented 3 years ago

I've seen it cause the CPU usage to skyrocket on an iPhone 8. Reason being that I'm presenting a dialog similar to the center presentation example.However on the smaller screen phone the presented controller is too big for the screen and only the overlay is shown, blocking the presenting controller with a transparent UIView and causing the CPU usage to go to 100%

I can't step through to see what it's doing until I figure out how to turn optimization off on the pod

DevTchernov commented 3 years ago

I've some issue and I found reason in my code (not in library) and yes, that issue wasn't reproduce on small iPhone's without additional safe area at the bottom. My container view was created from .xib file and some elements inside have layout constraints linked to safe area, which can cause endless layout call cycle if that view should be moved animated or have additional constraints with high priority. I've link constraints to superview and all works fine now