#ios #swift
Вопрос:
У меня есть а UIScrollView
, и внутри есть UIView
А. Я хочу показать UIColorPickerViewController
, когда пользователь долго нажимает на это представление. Вид прокрутки можно увеличивать/уменьшать. Проблема в том, что когда я увеличиваю изображение прокрутки и вид внутри почти равен или превышает границы устройства, всплывающее окно не отображается при длительном нажатии. Это происходит для любого UIViewController
, показанного в качестве всплывающего окна. Проблема возникает только внутри iPads
и отлично работает внутри iPhones
.
У кого-нибудь есть идеи, почему это происходит?
Работает, как и ожидалось, в iPhone
В iPad, если я просто увеличу немного больше второй сценарий(второе изображение), всплывающее окно не будет отображаться при длительном нажатии.
Это пример кода
class ScrollViewController: UIViewController {
let scrollView = UIScrollView()
let colorView = UIView()
override func loadView() {
super.loadView()
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(showColorPicker(_:)))
colorView.frame = CGRect(x: 200, y: 200, width: 400, height: 400)
colorView.backgroundColor = .systemBlue
colorView.addGestureRecognizer(longPressRecognizer)
colorView.isUserInteractionEnabled = true
scrollView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
scrollView.contentSize = CGSize(width: self.view.frame.width, height: 4000)
scrollView.minimumZoomScale = 0.1
scrollView.maximumZoomScale = 10
scrollView.delegate = self
scrollView.backgroundColor = .white
scrollView.addSubview(colorView)
self.view.addSubview(scrollView)
}
@objc func showColorPicker(_ sender: UITapGestureRecognizer) {
let colorPicker = UIColorPickerViewController()
colorPicker.modalPresentationStyle = .popover
colorPicker.popoverPresentationController?.canOverlapSourceViewRect = true
colorPicker.popoverPresentationController?.sourceView = colorView
colorPicker.popoverPresentationController?.sourceRect = self.colorView.bounds
colorPicker.popoverPresentationController?.permittedArrowDirections = .any
self.present(colorPicker, animated: true, completion: nil)
}
}
extension ScrollViewController: UIScrollViewDelegate {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return scrollView.subviews.first
}
}
Ответ №1:
В качестве обходного пути для этой проблемы мы можем указать a sourceRect
, которое находится внутри границ устройства , когда sourceView
оно больше границ устройства.
@objc func showColorPicker(_ sender: UITapGestureRecognizer) {
let colorPicker = UIColorPickerViewController()
colorPicker.modalPresentationStyle = .popover
colorPicker.popoverPresentationController?.canOverlapSourceViewRect = true
colorPicker.popoverPresentationController?.sourceView = self.colorView
colorPicker.popoverPresentationController?.permittedArrowDirections = .any
let point = sender.location(in: self.colorView)
//set a sourceRect which is guranteed to be inside the device bounds when the colorView exceeds the devie bounds
if (scrollView.bounds.size.width - self.colorView.frame.width) < 0 || (scrollView.bounds.size.height - self.colorView.frame.height) < 0 {
colorPicker.popoverPresentationController?.sourceRect = CGRect(origin: point, size: CGSize(width: 1, height: 1))
} else {
colorPicker.popoverPresentationController?.sourceRect = self.colorView.bounds
}
self.present(colorPicker, animated: true, completion: nil)
}