添加新的 UIView 后如何删除以前的堆栈?
How to remove previous stack of UIView after adding a new one?
我想每次右滑添加一个新的子视图,但是如果我不破坏之前的子视图,它会堆叠很多次。我知道如何删除它,但我正在为如何在添加一个新的之后才删除它的逻辑而苦苦挣扎。
我试过这个:
var view1: UIView?
var view2: UIView?
var ctrl = false
override func viewDidLoad() {
super.viewDidLoad()
view1?.addSubview(CustomView(frame: self.view.bounds))
}
func addView(){
if let test1 = view1, let test2 = view2 {
if ctrl == true {
test1.addSubview(CustomView(frame: self.view.bounds))
test2.removeFromSuperview()
ctrl = false
}else{
test2.addSubview(CustomView(frame: self.view.bounds))
test1.removeFromSuperview()
ctrl = true
}
}
}
@IBAction func swipeRight(_ sender: Any) {
print("Right")
UIView.animate(withDuration: 1, animations: {
self.view.layer.backgroundColor = .black
}){(isFinished) in
self.addView()
//I am hoping that after this the view stack before will be removed
}
}
Class CustomView 是这样的:
var primaryColors: [UIColor] = [
.red,
.yellow,
.blue]
class CustomView: UIView {
override func draw(_ rect: CGRect) {
super.draw(rect)
primaryColors.shuffle()
let leftRect = CGRect(x: 0, y: 0, width: rect.size.width/2, height: rect.size.height)
primaryColors[0].set()
guard let leftContext = UIGraphicsGetCurrentContext() else { return }
leftContext.fill(leftRect)
let rightRect = CGRect(x: rect.size.width/2, y: 0, width: rect.size.width/2, height: rect.size.height)
primaryColors[1].set()
guard let rightContext = UIGraphicsGetCurrentContext() else { return }
rightContext.fill(rightRect)
}
}
它可能不起作用。在您使用的 addSubview 方法的 if 条件中:
if let test1 = view1, let test2 = view2
检查 view1
和 view2
都不是 nil
。
这一定是失败了,因为您只在 viewDidLoad()
中初始化了 view1
:
view1?.addSubview(CustomView(frame: self.view.bounds))
。所以在上面,如果条件 view2
必须为 nil,因此它将评估为 false
.
尝试像这样放置您的 if 条件:
if let test1 = view1 || let test2 = view2
(如果出现错误则检查语法,ll
将在 if 条件下出现错误)。如果它不起作用,请告诉我。试试下面的代码:
if((self.view1 != nil) || (self.view2 != nil){
if ctrl == true {
self.view1?.addSubview(CustomView(frame: self.view.bounds))
self.view2?.removeFromSuperview()
ctrl = false
}else{
self.view2?.addSubview(CustomView(frame: self.view.bounds))
self.view1?.removeFromSuperview()
ctrl = true
}
}
嗯,我不太擅长 swift,但在我理解您的问题之前,这应该可以解决问题。
如果没有,我很确定 swift 中更好的人会以更好的方式回答它。
每个 ViewController
都有一个基础 view
,您可以像 view.method()
一样访问它。
您将子视图添加到现有视图。
假设您要添加一个名为 view1 的新 UIView。
首先你初始化它,
view1 = UIView(frame: view.bounds)
现在让它出现在屏幕上,点赞,
view.addSubview(view1)
此行会将 view1
添加为 view
的子视图。
现在 view1
也在 view
之上。所以现在当您触摸屏幕时,它就是您正在访问的 view1
。
所以下次你向右滑动时,手势识别器应该是 view1
.
let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(swipeRightAction))
swipeRight.direction = UISwipeGestureRecognizer.Direction.right
view1.addGestureRecognizer(swipeRight)
这就是将向右滑动手势添加到视图 1 的方式。
现在,当您在屏幕上向右滑动时,swipeRightAction()
会被调用。
您可以从超级视图中删除此 view1
,例如,
view1.removeFromSuperView()
现在 view1 不见了,现在您可以通过与添加 view1
.
类似的过程添加 view2
看下面的代码,可能有关联。
//The old view that has to be replaced
var viewToBeRemoved : UIView!
//The new view that will replace the previous one
var viewToBeAdded : UIView!
override func viewDidLoad() {
super.viewDidLoad()
replaceWithNewSwipableSubview()
}
func replaceWithNewSwipableSubview()
{
viewToBeAdded = UIView(frame: view.bounds)
//New view being added should have a gesture so that next time
//it need to be replaced we can swipe on it
let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(swipeRightAction))
swipeRight.direction = UISwipeGestureRecognizer.Direction.right
viewToBeAdded.addGestureRecognizer(swipeRight)
UIView.animate(withDuration: 1, animations: {
//This will be animated
if self.viewToBeRemoved != nil{
//As there is no subview the very first time this func is called
self.viewToBeRemoved.removeFromSuperview()
}
//Because next time it will be the view to be removed
self.viewToBeRemoved = self.viewToBeAdded
}) { (isFinished) in
//This block gets executed only after
//the block above has completed
self.view.addSubview(self.viewToBeAdded)
//view is the default base view of a ViewController
}
}
@objc func swipeRightAction() {
replaceWithNewSwipableSubview()
}
在您的代码中 view1?.addSubview(CustomView(frame: self.view.bounds))
此行向 view1 添加了一个视图,您没有引用您正在添加的视图。您应该首先存储您添加的视图,如 view3 = CustomView(frame: self.view.bounds)
,以便稍后您可以删除 view3。另外,您的 view1
实际上永远不会被添加 如果我是对的,因为要添加 view1
您需要先添加 view.addSubview(view1)
。
尽管如果您告诉我们您实际想要实现的目标,可能会建议更好的解决方案?
我想每次右滑添加一个新的子视图,但是如果我不破坏之前的子视图,它会堆叠很多次。我知道如何删除它,但我正在为如何在添加一个新的之后才删除它的逻辑而苦苦挣扎。
我试过这个:
var view1: UIView?
var view2: UIView?
var ctrl = false
override func viewDidLoad() {
super.viewDidLoad()
view1?.addSubview(CustomView(frame: self.view.bounds))
}
func addView(){
if let test1 = view1, let test2 = view2 {
if ctrl == true {
test1.addSubview(CustomView(frame: self.view.bounds))
test2.removeFromSuperview()
ctrl = false
}else{
test2.addSubview(CustomView(frame: self.view.bounds))
test1.removeFromSuperview()
ctrl = true
}
}
}
@IBAction func swipeRight(_ sender: Any) {
print("Right")
UIView.animate(withDuration: 1, animations: {
self.view.layer.backgroundColor = .black
}){(isFinished) in
self.addView()
//I am hoping that after this the view stack before will be removed
}
}
Class CustomView 是这样的:
var primaryColors: [UIColor] = [
.red,
.yellow,
.blue]
class CustomView: UIView {
override func draw(_ rect: CGRect) {
super.draw(rect)
primaryColors.shuffle()
let leftRect = CGRect(x: 0, y: 0, width: rect.size.width/2, height: rect.size.height)
primaryColors[0].set()
guard let leftContext = UIGraphicsGetCurrentContext() else { return }
leftContext.fill(leftRect)
let rightRect = CGRect(x: rect.size.width/2, y: 0, width: rect.size.width/2, height: rect.size.height)
primaryColors[1].set()
guard let rightContext = UIGraphicsGetCurrentContext() else { return }
rightContext.fill(rightRect)
}
}
它可能不起作用。在您使用的 addSubview 方法的 if 条件中:
if let test1 = view1, let test2 = view2
检查 view1
和 view2
都不是 nil
。
这一定是失败了,因为您只在 viewDidLoad()
中初始化了 view1
:
view1?.addSubview(CustomView(frame: self.view.bounds))
。所以在上面,如果条件 view2
必须为 nil,因此它将评估为 false
.
尝试像这样放置您的 if 条件:
if let test1 = view1 || let test2 = view2
(如果出现错误则检查语法,ll
将在 if 条件下出现错误)。如果它不起作用,请告诉我。试试下面的代码:
if((self.view1 != nil) || (self.view2 != nil){
if ctrl == true {
self.view1?.addSubview(CustomView(frame: self.view.bounds))
self.view2?.removeFromSuperview()
ctrl = false
}else{
self.view2?.addSubview(CustomView(frame: self.view.bounds))
self.view1?.removeFromSuperview()
ctrl = true
}
}
嗯,我不太擅长 swift,但在我理解您的问题之前,这应该可以解决问题。 如果没有,我很确定 swift 中更好的人会以更好的方式回答它。
每个 ViewController
都有一个基础 view
,您可以像 view.method()
一样访问它。
您将子视图添加到现有视图。
假设您要添加一个名为 view1 的新 UIView。
首先你初始化它,
view1 = UIView(frame: view.bounds)
现在让它出现在屏幕上,点赞,
view.addSubview(view1)
此行会将 view1
添加为 view
的子视图。
现在 view1
也在 view
之上。所以现在当您触摸屏幕时,它就是您正在访问的 view1
。
所以下次你向右滑动时,手势识别器应该是 view1
.
let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(swipeRightAction))
swipeRight.direction = UISwipeGestureRecognizer.Direction.right
view1.addGestureRecognizer(swipeRight)
这就是将向右滑动手势添加到视图 1 的方式。
现在,当您在屏幕上向右滑动时,swipeRightAction()
会被调用。
您可以从超级视图中删除此 view1
,例如,
view1.removeFromSuperView()
现在 view1 不见了,现在您可以通过与添加 view1
.
view2
看下面的代码,可能有关联。
//The old view that has to be replaced
var viewToBeRemoved : UIView!
//The new view that will replace the previous one
var viewToBeAdded : UIView!
override func viewDidLoad() {
super.viewDidLoad()
replaceWithNewSwipableSubview()
}
func replaceWithNewSwipableSubview()
{
viewToBeAdded = UIView(frame: view.bounds)
//New view being added should have a gesture so that next time
//it need to be replaced we can swipe on it
let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(swipeRightAction))
swipeRight.direction = UISwipeGestureRecognizer.Direction.right
viewToBeAdded.addGestureRecognizer(swipeRight)
UIView.animate(withDuration: 1, animations: {
//This will be animated
if self.viewToBeRemoved != nil{
//As there is no subview the very first time this func is called
self.viewToBeRemoved.removeFromSuperview()
}
//Because next time it will be the view to be removed
self.viewToBeRemoved = self.viewToBeAdded
}) { (isFinished) in
//This block gets executed only after
//the block above has completed
self.view.addSubview(self.viewToBeAdded)
//view is the default base view of a ViewController
}
}
@objc func swipeRightAction() {
replaceWithNewSwipableSubview()
}
在您的代码中 view1?.addSubview(CustomView(frame: self.view.bounds))
此行向 view1 添加了一个视图,您没有引用您正在添加的视图。您应该首先存储您添加的视图,如 view3 = CustomView(frame: self.view.bounds)
,以便稍后您可以删除 view3。另外,您的 view1
实际上永远不会被添加 如果我是对的,因为要添加 view1
您需要先添加 view.addSubview(view1)
。
尽管如果您告诉我们您实际想要实现的目标,可能会建议更好的解决方案?