Skip to content

Commit

Permalink
defer PrimaryMenu menu creation
Browse files Browse the repository at this point in the history
  • Loading branch information
lkzhao committed Mar 31, 2024
1 parent f7d4c5c commit 07674de
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 13 deletions.
10 changes: 5 additions & 5 deletions Sources/UIComponent/Components/View/PrimaryMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ public class PrimaryMenu: UIControl {
public var isShowingMenu = false

/// The menu to be displayed when the control is interacted with.
public var menu: UIMenu? {
public var menuBuilder: (() -> UIMenu)? {
didSet {
guard isShowingMenu else { return }
if let menu {
if let menuBuilder {
contextMenuInteraction?.updateVisibleMenu({ _ in
return menu
return menuBuilder()
})
} else {
contextMenuInteraction?.dismissMenu()
Expand Down Expand Up @@ -149,8 +149,8 @@ public class PrimaryMenu: UIControl {

public override func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
(config ?? .default).didTap?(self)
let menuConfiguration = UIContextMenuConfiguration(actionProvider: { [menu] suggested in
return menu
let menuConfiguration = UIContextMenuConfiguration(actionProvider: { [menuBuilder] suggested in
return menuBuilder?()
})
if #available(iOS 16.0, *) {
menuConfiguration.preferredMenuElementOrder = self.preferredMenuElementOrder
Expand Down
20 changes: 12 additions & 8 deletions Sources/UIComponent/Components/View/PrimaryMenuComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,24 @@ public struct PrimaryMenuComponent: Component {
/// The underlying component that this `PrimaryMenuComponent` is wrapping.
public let component: any Component

/// The menu to be displayed as part of the primary menu component.
public let menu: UIMenu
/// A builder that constructs the menu to be displayed as part of the primary menu component.
public let menuBuilder: () -> UIMenu

public init(component: any Component, menu: UIMenu) {
public init(component: any Component, menuBuilder: @escaping () -> UIMenu) {
self.component = component
self.menu = menu
self.menuBuilder = menuBuilder
}

public init(component: any Component, menu: UIMenu) {
self.init(component: component, menuBuilder: { menu })
}

/// Lays out the component within the given constraints and returns a `PrimaryMenuRenderNode`.
/// - Parameter constraint: The constraints to use when laying out the component.
/// - Returns: A `PrimaryMenuRenderNode` representing the laid out component.
public func layout(_ constraint: Constraint) -> PrimaryMenuRenderNode {
let renderNode = component.layout(constraint)
return PrimaryMenuRenderNode(size: renderNode.size.bound(to: constraint), component: component, content: renderNode, menu: menu, config: config)
return PrimaryMenuRenderNode(size: renderNode.size.bound(to: constraint), component: component, content: renderNode, menuBuilder: menuBuilder, config: config)
}
}

Expand All @@ -46,8 +50,8 @@ public struct PrimaryMenuRenderNode: RenderNode {
/// The rendered content of the component.
public let content: any RenderNode

/// The menu to be displayed as part of the primary menu component.
public let menu: UIMenu?
/// A builder that constructs the menu to be displayed as part of the primary menu component.
public let menuBuilder: (() -> UIMenu)?

/// The configuration for the tappable view.
public let config: PrimaryMenuConfig?
Expand All @@ -61,7 +65,7 @@ public struct PrimaryMenuRenderNode: RenderNode {
/// - Parameter view: The `PrimaryMenu` to update.
public func updateView(_ view: PrimaryMenu) {
view.config = config
view.menu = menu
view.menuBuilder = menuBuilder
view.contentView.engine.reloadWithExisting(component: component, renderNode: content)
}
}
Expand Down

0 comments on commit 07674de

Please sign in to comment.