Skip to content

Update SwiftMessage Layout Improvements [WIP]#585

Open
mofeejegi wants to merge 10 commits intowork/10.1.0-basefrom
work/10.1.0-merge-candidate
Open

Update SwiftMessage Layout Improvements [WIP]#585
mofeejegi wants to merge 10 commits intowork/10.1.0-basefrom
work/10.1.0-merge-candidate

Conversation

@mofeejegi
Copy link
Contributor

@mofeejegi mofeejegi commented Jan 21, 2026

This PR brings forward a set of layout and segue improvements originally developed for an older version, updating them to align with the current release.

The changes introduce new segue classes and improve storyboard constraints and runtime attributes to enable more flexible message layouts. The work has been reconciled with the latest SwiftMessages updates, including recent iOS 26 changes.

The goal is to preserve and modernize prior layout work while ensuring full compatibility with the current release.

wtmoose and others added 8 commits July 13, 2021 15:06
…ages into work/10.0.0-new2

# Conflicts:
#	SwiftMessages.podspec
#	SwiftMessages.xcodeproj/project.pbxproj
#	SwiftMessages/SwiftMessages.swift
# Conflicts:
#	Demo/Demo/Base.lproj/Main.storyboard
#	SwiftMessages.podspec
#	SwiftMessages.xcodeproj/project.pbxproj
#	SwiftMessages/BaseView.swift
#	SwiftMessages/EdgeAnimation.swift
#	SwiftMessages/PhysicsAnimation.swift
#	SwiftMessages/SwiftMessagesSegue.swift
#	SwiftMessages/UIViewController+Extensions.swift
Copilot AI review requested due to automatic review settings January 21, 2026 14:44
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces layout improvements to SwiftMessages by adding support for leading/trailing message animations and refactoring the constraint system. The changes include renaming TopBottomAnimation to EdgeAnimation, introducing a new Layout configuration system with flexible boundary and dimension specifications, and adding new layout segue classes.

Changes:

  • Renamed TopBottomAnimation to EdgeAnimation and added leading/trailing animation support
  • Introduced new Layout struct with flexible inset, size, and center configuration
  • Added new segue layout types: .leadingMessage, .trailingMessage, .leadingCard, .trailingCard, .leadingTab, and .trailingTab

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
UILayoutPriority+Extensions.swift Defines new layout priority constants for the message sizing system
Layout.swift New layout definition system with protocols and configuration structs
SwiftMessagesSegue.swift Expanded layout options and refactored constraint configuration
EdgeAnimation.swift Renamed from TopBottomAnimation with added leading/trailing animation support
MaskingView.swift Implements layout constraint application logic
BaseView.swift Conforms to LayoutDefining protocol and removes deprecated methods
PhysicsAnimation.swift Updates to support LayoutDefining views
Presenter.swift Updates class references from TopBottomAnimation to EdgeAnimation
CornerRoundingView.swift Documentation updates for renamed class
MessageView.swift Minor comment correction
Animator.swift Updates AnimationContext to accept LayoutInstalling containers
TabView.xib Removes obsolete constraints and variations
CenteredView.xib Removes obsolete constraints and variations
CardView.xib Removes obsolete constraints and variations
ViewControllersViewController.swift Adds new segue class implementations for leading/trailing layouts
Main.storyboard XML formatting changes
project.pbxproj Updates file references for renamed EdgeAnimation file
Comments suppressed due to low confidence (3)

SwiftMessages/EdgeAnimation.swift:106

  • The empty do block serves no purpose and should be removed as it adds unnecessary clutter to the code.
    SwiftMessages/EdgeAnimation.swift:25
  • Type mismatch: The class defines its own Style enum with cases for top, bottom, leading, and trailing (lines 17-22), but the style property uses TopBottomAnimationStyle which only has top and bottom cases. This will cause compilation errors or prevent the new leading/trailing functionality from working. The property should be declared as public let style: Style instead of public let style: TopBottomAnimationStyle.
    SwiftMessages/EdgeAnimation.swift:77
  • There's a TODO comment indicating that proper leading and trailing animations need to be implemented. The current implementation may not be calculating transforms correctly for leading/trailing animations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +71 to +75
public struct Layout {
public var size = Size()
public var insets = Insets()
public var center = Center()
}
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a nested type naming conflict. The Layout struct has a nested type also called Layout (at line 71). This creates ambiguity and makes the code harder to understand. The nested Layout struct should be renamed to something more descriptive like MinMaxLayout or LayoutBounds.

Copilot uses AI. Check for mistakes.
Comment on lines 210 to 223
/// The self-retainer will not allow the segue, presenting and presented view controllers to be released if the presenting view controller
/// is removed without first dismissing. This monitor handles that scenario by setting `self.selfRetainer = nil` if
/// the presenting view controller is no longer in the heirarchy.
private func startReleaseMonitor() {
Task { @MainActor [weak self] in
try? await Task.sleep(seconds: 2)
guard let self = self else { return }
switch self.source.view.window {
case .none: self.selfRetainer = nil
case .some: self.startReleaseMonitor()
}
}
}
}
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method startReleaseMonitor should be an instance method of the SwiftMessagesSegue class. The current implementation has incorrect indentation and appears to be defined at the wrong scope level. The opening brace structure suggests this method should be inside the SwiftMessagesSegue class definition, not as a standalone function.

Suggested change
/// The self-retainer will not allow the segue, presenting and presented view controllers to be released if the presenting view controller
/// is removed without first dismissing. This monitor handles that scenario by setting `self.selfRetainer = nil` if
/// the presenting view controller is no longer in the heirarchy.
private func startReleaseMonitor() {
Task { @MainActor [weak self] in
try? await Task.sleep(seconds: 2)
guard let self = self else { return }
switch self.source.view.window {
case .none: self.selfRetainer = nil
case .some: self.startReleaseMonitor()
}
}
}
}
/// The self-retainer will not allow the segue, presenting and presented view controllers to be released if the presenting view controller
/// is removed without first dismissing. This monitor handles that scenario by setting `self.selfRetainer = nil` if
/// the presenting view controller is no longer in the heirarchy.
private func startReleaseMonitor() {
Task { @MainActor [weak self] in
try? await Task.sleep(seconds: 2)
guard let self = self else { return }
switch self.source.view.window {
case .none: self.selfRetainer = nil
case .some: self.startReleaseMonitor()
}
}
}
}

Copilot uses AI. Check for mistakes.
let view = context.messageView
self.context = context
UIView.animate(withDuration: hideDuration, delay: 0, options: [.beginFromCurrentState, .curveEaseIn], animations: {
UIView.animate(withDuration: hideDuration, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: [.beginFromCurrentState]) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverting this change. It broke the hide animation for bottom swift messages

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Define “broke”. I think this change was made for a reason

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looked like the reason was to explore a different kind of animation for the hide() action.
I figured when we start implementing the leading and trailing animation, we can revisit it.
For now, I reverted it back to its current state on master.

Here's the behaviour as it is on the current release compared to the behaviour introduced in the change:

Current Animation Broken Animation

NSLayoutConstraint.activate([
backgroundView.centerXAnchor.constraint(equalTo: centerXAnchor)
.with(priority: .belowMessageSizeable),
backgroundView.topAnchor.constraint(equalTo: topAnchor)
Copy link
Contributor Author

@mofeejegi mofeejegi Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excluding the layoutMarginsGuide.topAnchor and other layoutMarginsGuide anchors breaks the current behaviour of the background view - it now extends edge to edge horizontally and ignores the top safe area. An example can be seen in the "AnyView" in the demo.

With Layout Margin Guides Without Layout Margin Guides

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants