两个 类 使用相同的函数创建自定义视图 - Swift
Two classes to use the same function to create custom view - Swift
我是 Swift 的新手,我搞不懂。我有两个 classes,我需要使用相同的函数来设置自定义 UIStackVIew(显示评级星级的评级控件)。每个 class 都有一个名为 value
的变量需要在函数内部传递。我不想在每个 class 中复制 setUpStackView 函数的相同代码。我有以下代码:
class Class1: UIStackView {
var variable1 = "value1"
override init(frame: CGRect){
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder){
super.init(coder: aDecoder)
}
setUpStackView(value: variable1)
}
class Class2: UIStackView {
var variable2 = "value2"
override init(frame: CGRect){
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder){
super.init(coder: aDecoder)
}
setUpStackView(value: variable2)
}
extension Class1 {
func setUpStackView(value: String){
//code to set UIStackView rating control and to use the variable value
}
}
如何实现 Class2
的扩展?我坚持这个。任何帮助将不胜感激!
你有很多选择。
您可以让 Class2 继承自 Class1:
class Class2: Class1 {
var value = "value2" //You have access to Class1's value, so you can change it here
setUpStackView(value: value) //But there's a problem here
}
但是您不能在 class 声明的中间调用函数。
但是你可以在初始化器中这样做:
class Class2: Class1 {
override init(frame: CGRect) {
super.init(frame: frame)
value = "value2"
setUpStackView(value: value)
}
required init(coder aDecoder: NSCoder){
super.init(coder: aDecoder)
value = "value2"
setUpStackView(value: value)
}
}
上面的代码有点乱,因为您在它自己的初始化程序中引用了 class 属性。
这是另一个解决方案:
您可以使您的设置功能成为 UIStackView 的功能扩展:
extension UIStackView {
func setUpStackView(value: String) {
//Your setup here
self.someProperty = value //self is referring to the stackview itself
}
}
另一种选择是创建静态函数。
extension Class1 {
static func setUpStackView(stackVw: UIStackView, value: String) {
stackVw.someProperty = value
//Doing it like this still makes this function "belong" to Class1
//It also makes it so anyone can set up their stack view like
//this because they have to pass their stack view in here
}
}
不管你在什么 class 以及你有什么继承层次,用法都是这样的:
override init(frame: CGRect) {
super.init(frame: frame)
Class1.setUpStackVw(stackVw: self, value: self.variable)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
Class1.setUpStackVw(stackVw: self, value: self.variable)
}
另一种选择是创建一个 Class1 和 Class2 都遵守的协议。
protocol StackVwWithSpecialSetUp where Self: UIStackView {
var value: String {get}
}
extension StackVwWithSpecialSetUp {
func setUpStackView()
{
self.someProperty = self.value
}
}
然后您的 class 将符合它
class Class1Or2: UIStackView, StackVwWithSpecialSetUp {
var value: String = "blah" //Compiler will force you to implement this
override init(frame: CGRect) {
super.init(frame: frame)
//Now you can use this
setUpStackVw()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
//You can use this here too
setUpStackVw()
}
}
也许我的做法是完全消除对 value
属性 的需求:
class Class1: UIStackView {
override init(frame: CGRect) {
super.init(frame: frame)
setUpStackVw()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setUpStackVw()
}
func setUpStackVw()
{
self.accessibilityHint = "value1"
}
}
//////////
class Class2: Class1 {
override func setUpStackVw()
{
self.someProperty = "value2"
}
}
一个解决方案可以将通用代码移动到可以抽象出来的协议中:
protocol BaseStackView {
var variable :String { get set }
}
class Class1: UIStackView,BaseStackView {
var variable = "value1"
override init(frame: CGRect){
super.init(frame: frame)
self.setUpStackView(value: variable)
}
required init(coder: NSCoder) {
super.init(coder: coder)
self.setUpStackView(value: variable)
}
}
class Class2: UIStackView,BaseStackView {
var variable = "value2"
override init(frame: CGRect){
super.init(frame: frame)
self.setUpStackView(value: variable)
}
required init(coder: NSCoder) {
super.init(coder: coder)
self.setUpStackView(value: variable)
}
}
extension UIStackView {
func setUpStackView(value: String) {
//Your setup here
}
}
我是 Swift 的新手,我搞不懂。我有两个 classes,我需要使用相同的函数来设置自定义 UIStackVIew(显示评级星级的评级控件)。每个 class 都有一个名为 value
的变量需要在函数内部传递。我不想在每个 class 中复制 setUpStackView 函数的相同代码。我有以下代码:
class Class1: UIStackView {
var variable1 = "value1"
override init(frame: CGRect){
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder){
super.init(coder: aDecoder)
}
setUpStackView(value: variable1)
}
class Class2: UIStackView {
var variable2 = "value2"
override init(frame: CGRect){
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder){
super.init(coder: aDecoder)
}
setUpStackView(value: variable2)
}
extension Class1 {
func setUpStackView(value: String){
//code to set UIStackView rating control and to use the variable value
}
}
如何实现 Class2
的扩展?我坚持这个。任何帮助将不胜感激!
你有很多选择。
您可以让 Class2 继承自 Class1:
class Class2: Class1 {
var value = "value2" //You have access to Class1's value, so you can change it here
setUpStackView(value: value) //But there's a problem here
}
但是您不能在 class 声明的中间调用函数。 但是你可以在初始化器中这样做:
class Class2: Class1 {
override init(frame: CGRect) {
super.init(frame: frame)
value = "value2"
setUpStackView(value: value)
}
required init(coder aDecoder: NSCoder){
super.init(coder: aDecoder)
value = "value2"
setUpStackView(value: value)
}
}
上面的代码有点乱,因为您在它自己的初始化程序中引用了 class 属性。 这是另一个解决方案:
您可以使您的设置功能成为 UIStackView 的功能扩展:
extension UIStackView {
func setUpStackView(value: String) {
//Your setup here
self.someProperty = value //self is referring to the stackview itself
}
}
另一种选择是创建静态函数。
extension Class1 {
static func setUpStackView(stackVw: UIStackView, value: String) {
stackVw.someProperty = value
//Doing it like this still makes this function "belong" to Class1
//It also makes it so anyone can set up their stack view like
//this because they have to pass their stack view in here
}
}
不管你在什么 class 以及你有什么继承层次,用法都是这样的:
override init(frame: CGRect) {
super.init(frame: frame)
Class1.setUpStackVw(stackVw: self, value: self.variable)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
Class1.setUpStackVw(stackVw: self, value: self.variable)
}
另一种选择是创建一个 Class1 和 Class2 都遵守的协议。
protocol StackVwWithSpecialSetUp where Self: UIStackView {
var value: String {get}
}
extension StackVwWithSpecialSetUp {
func setUpStackView()
{
self.someProperty = self.value
}
}
然后您的 class 将符合它
class Class1Or2: UIStackView, StackVwWithSpecialSetUp {
var value: String = "blah" //Compiler will force you to implement this
override init(frame: CGRect) {
super.init(frame: frame)
//Now you can use this
setUpStackVw()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
//You can use this here too
setUpStackVw()
}
}
也许我的做法是完全消除对 value
属性 的需求:
class Class1: UIStackView {
override init(frame: CGRect) {
super.init(frame: frame)
setUpStackVw()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setUpStackVw()
}
func setUpStackVw()
{
self.accessibilityHint = "value1"
}
}
//////////
class Class2: Class1 {
override func setUpStackVw()
{
self.someProperty = "value2"
}
}
一个解决方案可以将通用代码移动到可以抽象出来的协议中:
protocol BaseStackView {
var variable :String { get set }
}
class Class1: UIStackView,BaseStackView {
var variable = "value1"
override init(frame: CGRect){
super.init(frame: frame)
self.setUpStackView(value: variable)
}
required init(coder: NSCoder) {
super.init(coder: coder)
self.setUpStackView(value: variable)
}
}
class Class2: UIStackView,BaseStackView {
var variable = "value2"
override init(frame: CGRect){
super.init(frame: frame)
self.setUpStackView(value: variable)
}
required init(coder: NSCoder) {
super.init(coder: coder)
self.setUpStackView(value: variable)
}
}
extension UIStackView {
func setUpStackView(value: String) {
//Your setup here
}
}