0%

MMDraggableTagView实现排坑

最近需要实现个MMDraggableTagView来实现类似网易新闻中的新闻类型管理或者其他的应用中标签管理页面,同时需要它最好能够拖拽,同时可以有层级关系。在工程中我们使用了 SnapKit 来管理autolayout的constraints,这个三方库和 Masonry 类似,只是 one for ObjC, one for Swift.

问题列表(Swift菜鸟问题,熟练工略过)

1. 通过SnapKit,重复更新autolayout时,页面显示位置不正常
最初采用public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void)来添加constraints,但是重复使用会遗留下之前添加的constraints。需要使用public func remakeConstraints(_ closure: (_ make: ConstraintMaker) -> Void)来实现删除之前的constraints,并创建新的constraints。

2. 通过更新视图的constraints来实现视图的动画效果。
一开始通过在UIView的animate block中实现constraints更新,但是并没有动画效果
正确方法是:

1
2
3
4
UIView.animate(withDuration: 0.2, animations: {
self.relocateTags() // update autolayout constraints by SnapKit.
self.layoutIfNeeded() // call layout method if needed to update subviews.
})

需要调用layoutIfNeeded()来更新子页面,不然其实子视图不会更新位置,只更新constraints。

3. 视图被拖拽时,出现视图因为之前的关联对象的位移,而产生同样的位移
考虑是因为之前被拖拽视图设置的与周边子视图相关的constraints导致的。因此可以通过SnapKit中的public func removeConstraints()来直接删除所有的限制。但是因为删除了所有constraints,会导致视图移动到最初左上角的位置。因此采用了个折中的办法,

1
2
3
4
draggingCell!.snp.remakeConstraints { (make) in
make.top.equalTo(self).offset(draggingCell!.frame.origin.y)
make.left.equalTo(self).offset(draggingCell!.frame.origin.x)
}

更新他的constraints,删除与周边subviews相关的constraints,设置为与superview的相关关系。这样就不会因为相关的subviews的位置变化而影响自己的视图。

未完待续