有人能告诉我如何在iOS 10的新苹果地图应用程序中模仿底部表格吗?
在Android中,你可以使用一个BottomSheet来模仿这种行为,但我在iOS中找不到任何类似的东西。
这是一个简单的带有内容嵌入的滚动视图,以便搜索栏在底部吗?
我对iOS编程相当陌生,所以如果有人能帮助我创建这个布局,那将是非常感谢的。
这就是我所说的“底稿”:
有人能告诉我如何在iOS 10的新苹果地图应用程序中模仿底部表格吗?
在Android中,你可以使用一个BottomSheet来模仿这种行为,但我在iOS中找不到任何类似的东西。
这是一个简单的带有内容嵌入的滚动视图,以便搜索栏在底部吗?
我对iOS编程相当陌生,所以如果有人能帮助我创建这个布局,那将是非常感谢的。
这就是我所说的“底稿”:
当前回答
**为iOS 15本机支持提供此**
@IBAction func openSheet() {
let secondVC = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController")
// Create the view controller.
if #available(iOS 15.0, *) {
let formNC = UINavigationController(rootViewController: secondVC!)
formNC.modalPresentationStyle = UIModalPresentationStyle.pageSheet
guard let sheetPresentationController = formNC.presentationController as? UISheetPresentationController else {
return
}
sheetPresentationController.detents = [.medium(), .large()]
sheetPresentationController.prefersGrabberVisible = true
present(formNC, animated: true, completion: nil)
} else {
// Fallback on earlier versions
}
}
其他回答
也许你可以试试我的答案https://github.com/AnYuan/AYPannel,灵感来自滑轮。从移动抽屉到滚动列表的平稳过渡。我在容器滚动视图中添加了一个平移手势,并设置shouldRecognizeSimultaneouslyWithGestureRecognizer返回YES。更多细节在我的github链接上面。希望能帮上忙。
我不知道新地图应用程序的底部表单是如何响应用户交互的。但您可以创建一个自定义视图,看起来就像屏幕截图中的视图,并将其添加到主视图中。
我想你知道如何:
1-通过故事板或使用xib文件创建视图控制器。
2-使用谷歌地图或苹果的MapKit。
例子
创建2个视图控制器,例如MapViewController和BottomSheetViewController。第一个控制器将承载映射,第二个控制器是底层表本身。
配置MapViewController
创建一个方法来添加底层工作表视图。
func addBottomSheetView() {
// 1- Init bottomSheetVC
let bottomSheetVC = BottomSheetViewController()
// 2- Add bottomSheetVC as a child view
self.addChildViewController(bottomSheetVC)
self.view.addSubview(bottomSheetVC.view)
bottomSheetVC.didMoveToParentViewController(self)
// 3- Adjust bottomSheet frame and initial position.
let height = view.frame.height
let width = view.frame.width
bottomSheetVC.view.frame = CGRectMake(0, self.view.frame.maxY, width, height)
}
并在viewDidAppear方法中调用它:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
addBottomSheetView()
}
配置BottomSheetViewController
1)准备背景
创建一个方法来添加模糊和振动效果
func prepareBackgroundView(){
let blurEffect = UIBlurEffect.init(style: .Dark)
let visualEffect = UIVisualEffectView.init(effect: blurEffect)
let bluredView = UIVisualEffectView.init(effect: blurEffect)
bluredView.contentView.addSubview(visualEffect)
visualEffect.frame = UIScreen.mainScreen().bounds
bluredView.frame = UIScreen.mainScreen().bounds
view.insertSubview(bluredView, atIndex: 0)
}
在viewWillAppear中调用这个方法
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
prepareBackgroundView()
}
确保你的控制器视图背景颜色是clearColor。
2)动画bottomSheet外观
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
UIView.animateWithDuration(0.3) { [weak self] in
let frame = self?.view.frame
let yComponent = UIScreen.mainScreen().bounds.height - 200
self?.view.frame = CGRectMake(0, yComponent, frame!.width, frame!.height)
}
}
3)修改你的xib,你想要的。
4)在视图中添加Pan Gesture Recognizer。
在你的viewDidLoad方法中添加UIPanGestureRecognizer。
override func viewDidLoad() {
super.viewDidLoad()
let gesture = UIPanGestureRecognizer.init(target: self, action: #selector(BottomSheetViewController.panGesture))
view.addGestureRecognizer(gesture)
}
并执行你的手势行为:
func panGesture(recognizer: UIPanGestureRecognizer) {
let translation = recognizer.translationInView(self.view)
let y = self.view.frame.minY
self.view.frame = CGRectMake(0, y + translation.y, view.frame.width, view.frame.height)
recognizer.setTranslation(CGPointZero, inView: self.view)
}
可滚动的底页:
如果你的自定义视图是一个滚动视图或任何其他继承的视图,那么你有两个选择:
第一:
使用头视图设计视图,并将panGesture添加到头视图。(糟糕的用户体验)。
第二:
1 -添加panGesture到bottom sheet视图。
实现UIGestureRecognizerDelegate,并将panGesture delegate设置为控制器。
实现shouldrecognizesimulouslywith委托函数,并在以下两种情况下禁用scrollView isScrollEnabled属性:
视图部分可见。 视图是完全可见的,scrollView的contenttoffset属性为0,用户正在向下拖动视图。
否则启用滚动。
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
let gesture = (gestureRecognizer as! UIPanGestureRecognizer)
let direction = gesture.velocity(in: view).y
let y = view.frame.minY
if (y == fullView && tableView.contentOffset.y == 0 && direction > 0) || (y == partialView) {
tableView.isScrollEnabled = false
} else {
tableView.isScrollEnabled = true
}
return false
}
NOTE
如果你将. allowuserinteraction设置为一个动画选项,就像在示例项目中一样,那么如果用户向上滚动,你需要在动画完成闭包上启用滚动。
示例项目
我在这个回购上创建了一个具有更多选项的示例项目,这可能会让您更好地了解如何自定义流程。
在演示中,addBottomSheetView()函数控制应将哪个视图用作底层表。
项目示例截图
—局部视图
——FullView
—可滚动视图
我写了自己的库来实现ios地图应用程序的预期行为。这是一个面向协议的解决方案。因此,您不需要继承任何基类,而是创建一个表控制器,并按照您的意愿进行配置。它还支持内部导航/表示,有或没有UINavigationController。
更多细节请参见下面的链接。
https://github.com/OfTheWolf/UBottomSheet
你可以试试我的答案https://github.com/SCENEE/FloatingPanel。它提供了一个容器视图控制器来显示“底层表”接口。
它很容易使用,你不介意任何手势识别器处理!如果需要,还可以在底部表单中跟踪滚动视图(或兄弟视图)。
这是一个简单的例子。请注意,你需要准备一个视图控制器来在底部表单中显示你的内容。
import UIKit
import FloatingPanel
class ViewController: UIViewController {
var fpc: FloatingPanelController!
override func viewDidLoad() {
super.viewDidLoad()
fpc = FloatingPanelController()
// Add "bottom sheet" in self.view.
fpc.add(toParent: self)
// Add a view controller to display your contents in "bottom sheet".
let contentVC = ContentViewController()
fpc.set(contentViewController: contentVC)
// Track a scroll view in "bottom sheet" content if needed.
fpc.track(scrollView: contentVC.tableView)
}
...
}
下面是另一个示例代码,用于显示底部表单以搜索Apple Maps之类的位置。
**为iOS 15本机支持提供此**
@IBAction func openSheet() {
let secondVC = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController")
// Create the view controller.
if #available(iOS 15.0, *) {
let formNC = UINavigationController(rootViewController: secondVC!)
formNC.modalPresentationStyle = UIModalPresentationStyle.pageSheet
guard let sheetPresentationController = formNC.presentationController as? UISheetPresentationController else {
return
}
sheetPresentationController.detents = [.medium(), .large()]
sheetPresentationController.prefersGrabberVisible = true
present(formNC, animated: true, completion: nil)
} else {
// Fallback on earlier versions
}
}