Ios 如何在自定义视图类中动态替换自定义子视图?
给定两个类型为Ios 如何在自定义视图类中动态替换自定义子视图?,ios,uiview,Ios,Uiview,给定两个类型为RoundedIcon:UIView的视图: class ContactRoundedIcon:RoundedIcon class-phone-RoundedIcon:RoundedIcon 以及ui视图类型的ContactItem类 class ContactItem: UIView { var icon: RoundedIcon = PhoneRoundedIcon() override init(frame: CGRect) { supe
RoundedIcon:UIView
的视图:
class ContactRoundedIcon:RoundedIcon
class-phone-RoundedIcon:RoundedIcon
ui视图类型的ContactItem
类
class ContactItem: UIView {
var icon: RoundedIcon = PhoneRoundedIcon()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
translatesAutoresizingMaskIntoConstraints = false
addSubview(icon)
}
/* ... */
NSLayoutConstraint.activate([
icon.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0),
icon.topAnchor.constraint(equalTo: topAnchor, constant: 0)
)]
}
和类类联系人下拉列表:UIControl
当我将ContactRoundedIcon
分配给contactItem.icon
属性时
class ContactDropDownList: UIControl {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
let contactItem = ContactItem()
contactItem.icon = ContactRoundedIcon()
self.addSubview(contactItem)
}
然后图标不会从PhoneRoundedIcon
更改为ContactRoundedIcon
。至少我没有在模拟器上看到它
ContactDropDownList
视图作为子视图添加到情节提要中。其余视图是以编程方式编写的。而他们自己,他们是好的。ContactItem
实例中的图标分配不起任何作用
怎么了?如何更改图标?尝试以下操作:
class ContactItem: UIView {
var icon: RoundedIcon = PhoneRoundedIcon() {
didSet {
// get rid of the old icon
oldValue.removeFromSuperview()
// add a new one
addSubview(icon)
// setup layout (I'm not sure if you use autolayout or set frames, but I don't see any layout setup, which might also be a problem)
}
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
translatesAutoresizingMaskIntoConstraints = false
addSubview(icon)
}
...
}
在didSet
中,您需要去掉旧图标,并在视图中添加一个新图标。否则,您看到旧图标是正常的(在初始值设定项中调用'commonInit',当您设置新图标时,它已全部设置好,不会再次调用)
此外,您还没有显示任何布局代码,因此,如果使用自动布局,请确保正确设置了框架或约束
编辑
就其本身而言,不必删除旧视图。但是你应该把它拿走,除非你真的有什么好的理由把它放在那里。首先,您希望释放未使用的对象。通过将其保留在视图中,您将保留它。其次,如果新的图标
有一些透明部分(或比旧的小),则旧的图标
的部分将可见。我猜你也不想要。你是否在其init
中为ContactRoundedIcon
设置了一个框架。自动布局工作正常,我已经仔细检查过了。你好,米兰,谢谢!。您能解释一下为什么需要删除旧视图,而分配不同的视图对象和调用setNeedsDipslay(
)不起作用吗?关于第一个问题,请参阅我对问题的编辑。第二点:我认为setNeedsDisplay()
是可行的(我没有理由相信会是这样)。为什么它没有达到你所期望的,我说不出来。您提供的代码不显示如何设置UI组件的框架,也不显示自动布局的约束。如果您没有为“自动布局”设置框架或约束,那么您就有了答案-视图不知道将其子视图放置在何处。如果你设置了框架和约束,那么你必须向我们展示代码来帮助你。米兰,谢谢你的进一步解释。我已编辑问题以添加布局代码。所有视图都基于约束。RoundedIcon
类设置图标的高度和宽度。所有视图都将translateAutoResizengMask
设置为false
。一般来说,您的解决方案工作得非常出色,我只是想知道为什么setNeedsDisplay不起作用。作为自动布局约束的旁注-我只希望您也在新的图标的didSet
中设置它们。回到设置需要显示
-您认为它不工作是什么意思?当你把它叫做什么时候,你期望会发生什么,会发生什么?是的,我添加了新的约束。旧视图将与旧视图一起删除。回到setNeedsDisplay
——我的想法是,如果我将一个新的视图对象引用分配给icon属性,那么在某个时间点,旧的视图对象引用将自动取消分配。我希望旧视图将被替换,我需要的是重新绘制视图。但这并不奏效。