在iOS 13中以自定义高度显示模式

时间:2019-09-19 09:17:43

标签: objective-c iphone user-interface ios13

在iOS 13中,当呈现模态视图控制器时有一个新行为。我发现内置的App Photo呈现了一个较小的模型视图控制器。

我该如何呈现一个具有这样的自定义尺寸的viewController,并且可以向上滑动到更大的高度?

smaller height

larger height

系统照片应用中的图片截图。

3 个答案:

答案 0 :(得分:3)

是的,可以在 iOS 13 中使用自定义高度显示模态。 您只需要将以下代码添加到您的演示模式

 override func updateViewConstraints() {
        self.view.frame.size.height = UIScreen.main.bounds.height - 150
        self.view.frame.origin.y =  150
        self.view.roundCorners(corners: [.topLeft, .topRight], radius: 10.0)
        super.updateViewConstraints()
 }

 extension UIView {
   func roundCorners(corners: UIRectCorner, radius: CGFloat) {
        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        layer.mask = mask
    }
 }

答案 1 :(得分:0)

我不认为使用标准的UIViewController实现是可行的-即使用iOS 13的新演示样式,也只是设置演示高度。

您可能想像这样研究第三方解决方案(或从中获得启发):

https://github.com/MarioIannotta/PullUpController

答案 2 :(得分:0)

Swift答案

我一直在寻找一种方法来复制这种ViewController行为,尽管它具有基本的UI,并且找到了一个相当简单的解决方案。 基本上,您创建一个具有透明背景的ViewController(CardViewContoller),然后向其中添加一个带有UIPanGestureReconizer的类似于卡片的视图,这将使您可以将其拖动并通过ViewController将其关闭。

要演示,您只需调用present,将modalPresentationStyle设置为.overCurrentContext,将modalTransitionStyle设置为.coverVertical

let cardVC = CardViewController()
cardVC.modalPresentationStyle = .overCurrentContext
cardVC.modalTransitionStyle = .coverVertical
present(cardVC, animated: true, completion: nil)

CardViewController中的UIPanGestureRecognizer可以通过编程方式创建,也可以使用Interface Builder创建,将contentView添加到名片视图(let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handleDismiss(recognizer:))) panGestureRecognizer.cancelsTouchesInView = false contentView.addGestureRecognizer(panGestureRecognizer) ):

@objc

然后只需添加一个 @objc func handleDismiss (recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .changed: viewTranslation = recognizer.translation(in: view) UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 1, options: .curveEaseOut, animations: { guard self.viewTranslation.y > 0 else {return} self.view.transform = CGAffineTransform(translationX: 0, y: self.viewTranslation.y) }) case .ended: if viewTranslation.y < swipeThreshold { UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 1, options: .curveEaseOut, animations: { self.view.transform = .identity }) } else { dismiss(animated: true, completion: nil) } default: break } } 函数即可响应UIPanGestureRecognizer:

swipeThreshold

CGFloat是一个UIPanGestureRecognizer变量,具有您选择的值( 200对我而言非常有用),如果.touchUpInside y转换超出,将触发ViewController及其所有元素的关闭。 同样,您可以添加一个简单的按钮,该按钮将在dismiss()调用<ListView x:Name="MainMenu" Foreground="#FF5C99D6" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" Focusable="False" VerticalAlignment="Top" SelectedItem="{Binding SelectedMenuItem}" ItemsSource="{Binding MenuItems}"> <ListView.ItemContainerStyle> <Style x:Name="TestStyleName" TargetType="ListViewItem" BasedOn="{StaticResource {x:Type ListViewItem}}"> <EventSetter x:Name="TestEventName" Event="PreviewMouseLeftButtonDown" Handler="ListViewItem_PreviewMouseLeftButtonDown" /> <Style.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="true" /> <Condition Property="Selector.IsSelectionActive" Value="true" /> </MultiTrigger.Conditions> <Setter Property="Foreground" Value="Yellow" /> </MultiTrigger> </Style.Triggers> </Style> </ListView.ItemContainerStyle> <!--REGION MAIN MENU--> <ListViewItem x:Name="MainHome" Height="60"> <StackPanel Orientation="Horizontal"> <materialDesign:PackIcon Kind="Home" Height="25" Width="25" Margin="10"/> <TextBlock Text="Home" VerticalAlignment="Center" Margin="20 10"/> </StackPanel> </ListViewItem> <ListViewItem x:Name="MainSearch" Height="60"> <StackPanel Orientation="Horizontal"> <materialDesign:PackIcon Kind="Magnify" Height="25" Width="25" Margin="10"/> <TextBlock Text="Search" VerticalAlignment="Center" Margin="20 10"/> </StackPanel> </ListViewItem> </ListView>

时关闭ViewController

如果需要,您可以看一下this repo,其中有一个展示这种行为的示例项目。这样,您可以构建自己的完全可定制的卡。