通过点击创建 UIView 时如何不让它们重叠?
How do I not let UIViews overlap when I create them by tapping?
我正在创建一个日历应用程序,我点击以在 UIScrollView 中创建新事件。可以把它想象成苹果日历的“日视图”,您可以在其中创建新事件并在滚动视图的列表中查看它们。每个事件都是一个带有 TextField 的 UIView,现在一切正常,但我不确定如何做到这一点,以便在创建事件时事件不会重叠。
有什么方法可以防止 UIView 在创建或移动时重叠?我只是将它们向上或向下移动,所以我只需要防止它们在 y 轴上重叠。现在我点击创建它们,但它们可以重叠。有没有办法把它们放在同一个平面上,这样它们就不能叠加在一起?
强烈建议您 post 您自己的代码,以便我们了解您的大体方向。否则,我们双方的努力都会白费。
例如,您提到“现在一切正常”,但我不知道您是如何以垂直方式移动视图的。我继续对手势识别器进行子类化,希望它适合您的代码流程。
import UIKit.UIGestureRecognizerSubclass
class ViewController: UIViewController {
let size = CGSize(width: 200, height: 100)
var v1: UIView!
var v2: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.v1 = UIView(frame: .init(origin: .init(x: 100, y: 100), size: size))
self.view.addSubview(self.v1)
self.v1.backgroundColor = .orange
self.v2 = UIView(frame: .init(origin: .init(x: 100, y: 300), size: size))
self.view.addSubview(v2)
self.view.addSubview(self.v2)
self.v2.backgroundColor = .purple
let verticalGesture = VerticalGesture(target: self, action: #selector(dragged))
self.v2.addGestureRecognizer(verticalGesture)
}
@objc func dragged(_ sender: VerticalGesture) {
}
}
class VerticalGesture: UIPanGestureRecognizer {
private var touch: UITouch!
private var currentView: UIView!
private var currentSuperview: UIView!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
guard let firstTouch = touches.first, let currentView = self.view, let currentSuperview = currentView.superview else { return }
self.touch = firstTouch
self.currentView = currentView
self.currentSuperview = currentSuperview
super.touchesBegan(touches, with: event)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
var center = self.currentView.center
let currentLocation = self.touch.location(in: self.currentSuperview)
let previousLocation = self.touch.previousLocation(in: self.currentSuperview)
let yTranslation = currentLocation.y - previousLocation.y
center.y += yTranslation
self.view!.center = center
super.touchesMoved(touches, with: event)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
for subview in self.currentSuperview.subviews {
// this goes through all the sibling views including the non-calendar-event views i.e. calendar dates, calendar frame, etc
// so make sure to sort those out
if subview != self.currentView! && self.currentView!.frame.intersects(subview.frame) {
var center = self.currentView.center
let isHigher = subview.center.y >= center.y
// isHigher >= 0 means the current view that you've selected is located higher
// than the overlapping view below
if isHigher {
center = CGPoint(x: subview.center.x, y: subview.center.y - self.currentView.bounds.height)
self.view!.center = center
} else {
center = CGPoint(x: subview.center.x, y: subview.center.y + self.currentView.bounds.height)
self.view!.center = center
}
}
}
super.touchesEnded(touches, with: event)
}
}
根据您拖动的日历事件是在重叠视图的上侧还是下侧,它会移动到相邻的位置。随意为其添加变换动画。
我正在创建一个日历应用程序,我点击以在 UIScrollView 中创建新事件。可以把它想象成苹果日历的“日视图”,您可以在其中创建新事件并在滚动视图的列表中查看它们。每个事件都是一个带有 TextField 的 UIView,现在一切正常,但我不确定如何做到这一点,以便在创建事件时事件不会重叠。
有什么方法可以防止 UIView 在创建或移动时重叠?我只是将它们向上或向下移动,所以我只需要防止它们在 y 轴上重叠。现在我点击创建它们,但它们可以重叠。有没有办法把它们放在同一个平面上,这样它们就不能叠加在一起?
强烈建议您 post 您自己的代码,以便我们了解您的大体方向。否则,我们双方的努力都会白费。
例如,您提到“现在一切正常”,但我不知道您是如何以垂直方式移动视图的。我继续对手势识别器进行子类化,希望它适合您的代码流程。
import UIKit.UIGestureRecognizerSubclass
class ViewController: UIViewController {
let size = CGSize(width: 200, height: 100)
var v1: UIView!
var v2: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.v1 = UIView(frame: .init(origin: .init(x: 100, y: 100), size: size))
self.view.addSubview(self.v1)
self.v1.backgroundColor = .orange
self.v2 = UIView(frame: .init(origin: .init(x: 100, y: 300), size: size))
self.view.addSubview(v2)
self.view.addSubview(self.v2)
self.v2.backgroundColor = .purple
let verticalGesture = VerticalGesture(target: self, action: #selector(dragged))
self.v2.addGestureRecognizer(verticalGesture)
}
@objc func dragged(_ sender: VerticalGesture) {
}
}
class VerticalGesture: UIPanGestureRecognizer {
private var touch: UITouch!
private var currentView: UIView!
private var currentSuperview: UIView!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
guard let firstTouch = touches.first, let currentView = self.view, let currentSuperview = currentView.superview else { return }
self.touch = firstTouch
self.currentView = currentView
self.currentSuperview = currentSuperview
super.touchesBegan(touches, with: event)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
var center = self.currentView.center
let currentLocation = self.touch.location(in: self.currentSuperview)
let previousLocation = self.touch.previousLocation(in: self.currentSuperview)
let yTranslation = currentLocation.y - previousLocation.y
center.y += yTranslation
self.view!.center = center
super.touchesMoved(touches, with: event)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
for subview in self.currentSuperview.subviews {
// this goes through all the sibling views including the non-calendar-event views i.e. calendar dates, calendar frame, etc
// so make sure to sort those out
if subview != self.currentView! && self.currentView!.frame.intersects(subview.frame) {
var center = self.currentView.center
let isHigher = subview.center.y >= center.y
// isHigher >= 0 means the current view that you've selected is located higher
// than the overlapping view below
if isHigher {
center = CGPoint(x: subview.center.x, y: subview.center.y - self.currentView.bounds.height)
self.view!.center = center
} else {
center = CGPoint(x: subview.center.x, y: subview.center.y + self.currentView.bounds.height)
self.view!.center = center
}
}
}
super.touchesEnded(touches, with: event)
}
}
根据您拖动的日历事件是在重叠视图的上侧还是下侧,它会移动到相邻的位置。随意为其添加变换动画。