如何使用 Eureka 创建自定义内联行?
How to create custom inline rows with Eureka?
我想像描述的那样用 Eureka 实现自定义 inline
cell
here。但是在我的具体案例中,我在编译时遇到了一些问题。 Swift 当我尝试 运行 时编译器崩溃并出现以下错误。
...
Call parameter type does not match function signature!
...
1. Running pass 'Module Verifier' on function'@_TWaC7TonyPro22ServiceCheckInlineRow26Eureka13InlineRowTypeS_'
...
我的可折叠行和单元格。
public final class ServiceRow: Row<Service, ServiceCell>, RowType {
...
}
public class ServiceCell: Cell<Service>, CellType {
...
}
我的内联行
public class ServiceCheckInlineRow: ImageCheckInlineRow<Service>, InlineRowType {
public typealias InlineRow = ServiceRow
required public init(tag: String?) {
super.init(tag: tag)
onExpandInlineRow { cell, row, _ in
let color = cell.detailTextLabel?.textColor
row.onCollapseInlineRow { cell, _, _ in
cell.detailTextLabel?.textColor = color
}
cell.detailTextLabel?.textColor = cell.tintColor
}
}
public override func customDidSelect() {
super.customDidSelect()
if !isDisabled {
toggleInlineRow()
}
}
public func setupInlineRow(inlineRow: InlineRow) {
}
}
public class ImageCheckInlineRow<T where T: Equatable, T: ServiceType>: Row<T, ImageCheckCell<T>>, SelectableRowType, RowType {
public var selectableValue: T?
required public init(tag: String?) {
super.init(tag: tag)
displayValueFor = nil
}
}
我认为问题的根源是 aliasType InlineRow
但我找不到原因。
你好,我一直在研究你的问题,这是我的结果,看起来是这样的
我将 post 两个带有 eureka 的自定义内联行示例
第一个示例是带有滑块的自定义内联行,滑块的值从 0..100
public class ServiceInlineCell<T: Equatable> : Cell<T>, CellType {
required public init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
public override func setup() {
super.setup()
accessoryType = .None
editingAccessoryType = .None
}
public override func update() {
super.update()
selectionStyle = row.isDisabled ? .None : .Default
}
public override func didSelect() {
super.didSelect()
row.deselect()
}
}
//MARK: PickerInlineRow
public class _ServiceInlineRow : Row<Float, ServiceInlineCell<Float>>, NoValueDisplayTextConformance {
public typealias InlineRow = SliderRow
public var options = [Float]()
public var noValueDisplayText: String?
required public init(tag: String?) {
super.init(tag: tag)
}
}
/// A generic inline row where the user can pick an option from a picker view
public final class ServiceInlineRow<T where T: Equatable> : _ServiceInlineRow, RowType, InlineRowType {
required public init(tag: String?) {
super.init(tag: tag)
onExpandInlineRow { cell, row, _ in
let color = cell.detailTextLabel?.textColor
row.onCollapseInlineRow { cell, _, _ in
cell.detailTextLabel?.textColor = color
}
cell.detailTextLabel?.textColor = cell.tintColor
}
}
public override func customDidSelect() {
super.customDidSelect()
if !isDisabled {
toggleInlineRow()
}
}
public func setupInlineRow(inlineRow: InlineRow) {
inlineRow.maximumValue = 100
inlineRow.steps = UInt(inlineRow.maximumValue / 10)
inlineRow.displayValueFor = {(Float) in
return "\(Float)"
}
}
}
然后在你的表格上你需要把这个
<<< ServiceInlineRow<Float>("PickerInlineRow") { (row : ServiceInlineRow<Float>) -> Void in
row.title = row.tag
row.value = 0
}
这是另一个带有滑块但带有字符串值的示例
public class CustomSliderInlineCell<T: Equatable> : Cell<T>, CellType {
required public init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
public override func setup() {
super.setup()
accessoryType = .None
editingAccessoryType = .None
}
public override func update() {
super.update()
selectionStyle = row.isDisabled ? .None : .Default
}
public override func didSelect() {
super.didSelect()
row.deselect()
}
}
//MARK: PickerInlineRow
public class _CustomSliderInlineRow<T where T: Equatable> : Row<T, CustomSliderInlineCell<T>>, NoValueDisplayTextConformance {
public typealias InlineRow = CustomSliderRow<T>
public var options = [T]()
public var noValueDisplayText: String?
required public init(tag: String?) {
super.init(tag: tag)
}
}
/// A generic inline row where the user can pick an option from a picker view
public final class CustomSliderInlineRow<T where T: Equatable> : _CustomSliderInlineRow<T>, RowType, InlineRowType {
required public init(tag: String?) {
super.init(tag: tag)
onExpandInlineRow { cell, row, _ in
let color = cell.detailTextLabel?.textColor
row.onCollapseInlineRow { cell, _, _ in
cell.detailTextLabel?.textColor = color
}
cell.detailTextLabel?.textColor = cell.tintColor
}
}
public override func customDidSelect() {
super.customDidSelect()
if !isDisabled {
toggleInlineRow()
}
}
public func setupInlineRow(inlineRow: InlineRow) {
inlineRow.values = options
inlineRow.displayValueFor = self.displayValueFor
}
}
以及 CustomSliderRow 和 Cell 的定义
public class CustomSliderCell<T: Equatable>: Cell<T>, CellType {
public required init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .Value1, reuseIdentifier: reuseIdentifier)
}
public var titleLabel: UILabel! {
textLabel?.translatesAutoresizingMaskIntoConstraints = false
textLabel?.setContentHuggingPriority(500, forAxis: .Horizontal)
return textLabel
}
public var valueLabel: UILabel! {
detailTextLabel?.translatesAutoresizingMaskIntoConstraints = false
detailTextLabel?.setContentHuggingPriority(500, forAxis: .Horizontal)
return detailTextLabel
}
lazy public var slider: UISlider = {
let result = UISlider()
result.translatesAutoresizingMaskIntoConstraints = false
result.setContentHuggingPriority(500, forAxis: .Horizontal)
return result
}()
public var formatter: NSNumberFormatter?
public override func setup() {
super.setup()
selectionStyle = .None
slider.minimumValue = sliderRow.minimumValue
slider.maximumValue = sliderRow.maximumValue
print(sliderRow.values.count)
slider.addTarget(self, action: #selector(CustomSliderCell.valueChanged), forControlEvents: .ValueChanged)
if shouldShowTitle() {
contentView.addSubview(titleLabel)
contentView.addSubview(valueLabel!)
}
contentView.addSubview(slider)
let views = ["titleLabel" : titleLabel, "valueLabel" : valueLabel, "slider" : slider]
let metrics = ["hPadding" : 16.0, "vPadding" : 12.0, "spacing" : 12.0]
if shouldShowTitle() {
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-hPadding-[titleLabel]-[valueLabel]-hPadding-|", options: NSLayoutFormatOptions.AlignAllBaseline, metrics: metrics, views: views))
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-vPadding-[titleLabel]-spacing-[slider]-vPadding-|", options: NSLayoutFormatOptions.AlignAllLeft, metrics: metrics, views: views))
} else {
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-vPadding-[slider]-vPadding-|", options: NSLayoutFormatOptions.AlignAllLeft, metrics: metrics, views: views))
}
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-hPadding-[slider]-hPadding-|", options: NSLayoutFormatOptions.AlignAllBaseline, metrics: metrics, views: views))
}
public override func update() {
super.update()
if !shouldShowTitle() {
textLabel?.text = nil
detailTextLabel?.text = nil
}
//slider.value = row.value ?? 0.0
slider.value = 0.0
}
func valueChanged() {
let roundedValue: Float
//let steps = Float(sliderRow.steps)
let steps = Float(sliderRow.values.count-1)
if steps > 0 {
let stepValue = round((slider.value - slider.minimumValue) / (slider.maximumValue - slider.minimumValue) * steps)
let stepAmount = (slider.maximumValue - slider.minimumValue) / steps
roundedValue = stepValue * stepAmount + self.slider.minimumValue
}
else {
roundedValue = slider.value
}
//row.value = roundedValue
row.value = sliderRow.values[Int(roundedValue)]
if shouldShowTitle() {
valueLabel.text = "\(row.value!)"
}
}
private func shouldShowTitle() -> Bool {
return row.title?.isEmpty == false
}
private var sliderRow: CustomSliderRow<T> {
return row as! CustomSliderRow
}
}
/// A row that displays a UISlider. If there is a title set then the title and value will appear above the UISlider.
public final class CustomSliderRow<T: Equatable>: Row<T, CustomSliderCell<T>>, RowType {
public var minimumValue: Float = 0.0
public var maximumValue: Float = 10.0
public var steps: UInt = 20
public var values : [T] = [T](){
willSet(newValues)
{
maximumValue = Float(newValues.count-1)
steps = UInt(newValues.count)
cell.setup()
}
}
required public init(tag: String?) {
super.init(tag: tag)
}
}
并且在您的表单中,您需要输入
<<< CustomSliderInlineRow<String>("CustomSliderRow"){ (row : CustomSliderInlineRow<String>) -> Void in
row.title = row.tag
row.options = ["Value1","Value2","Value3"]
row.value = "Value1"
}
希望对您有所帮助,问候
我想像描述的那样用 Eureka 实现自定义 inline
cell
here。但是在我的具体案例中,我在编译时遇到了一些问题。 Swift 当我尝试 运行 时编译器崩溃并出现以下错误。
...
Call parameter type does not match function signature!
...
1. Running pass 'Module Verifier' on function'@_TWaC7TonyPro22ServiceCheckInlineRow26Eureka13InlineRowTypeS_'
...
我的可折叠行和单元格。
public final class ServiceRow: Row<Service, ServiceCell>, RowType {
...
}
public class ServiceCell: Cell<Service>, CellType {
...
}
我的内联行
public class ServiceCheckInlineRow: ImageCheckInlineRow<Service>, InlineRowType {
public typealias InlineRow = ServiceRow
required public init(tag: String?) {
super.init(tag: tag)
onExpandInlineRow { cell, row, _ in
let color = cell.detailTextLabel?.textColor
row.onCollapseInlineRow { cell, _, _ in
cell.detailTextLabel?.textColor = color
}
cell.detailTextLabel?.textColor = cell.tintColor
}
}
public override func customDidSelect() {
super.customDidSelect()
if !isDisabled {
toggleInlineRow()
}
}
public func setupInlineRow(inlineRow: InlineRow) {
}
}
public class ImageCheckInlineRow<T where T: Equatable, T: ServiceType>: Row<T, ImageCheckCell<T>>, SelectableRowType, RowType {
public var selectableValue: T?
required public init(tag: String?) {
super.init(tag: tag)
displayValueFor = nil
}
}
我认为问题的根源是 aliasType InlineRow
但我找不到原因。
你好,我一直在研究你的问题,这是我的结果,看起来是这样的
我将 post 两个带有 eureka 的自定义内联行示例
第一个示例是带有滑块的自定义内联行,滑块的值从 0..100
public class ServiceInlineCell<T: Equatable> : Cell<T>, CellType {
required public init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
public override func setup() {
super.setup()
accessoryType = .None
editingAccessoryType = .None
}
public override func update() {
super.update()
selectionStyle = row.isDisabled ? .None : .Default
}
public override func didSelect() {
super.didSelect()
row.deselect()
}
}
//MARK: PickerInlineRow
public class _ServiceInlineRow : Row<Float, ServiceInlineCell<Float>>, NoValueDisplayTextConformance {
public typealias InlineRow = SliderRow
public var options = [Float]()
public var noValueDisplayText: String?
required public init(tag: String?) {
super.init(tag: tag)
}
}
/// A generic inline row where the user can pick an option from a picker view
public final class ServiceInlineRow<T where T: Equatable> : _ServiceInlineRow, RowType, InlineRowType {
required public init(tag: String?) {
super.init(tag: tag)
onExpandInlineRow { cell, row, _ in
let color = cell.detailTextLabel?.textColor
row.onCollapseInlineRow { cell, _, _ in
cell.detailTextLabel?.textColor = color
}
cell.detailTextLabel?.textColor = cell.tintColor
}
}
public override func customDidSelect() {
super.customDidSelect()
if !isDisabled {
toggleInlineRow()
}
}
public func setupInlineRow(inlineRow: InlineRow) {
inlineRow.maximumValue = 100
inlineRow.steps = UInt(inlineRow.maximumValue / 10)
inlineRow.displayValueFor = {(Float) in
return "\(Float)"
}
}
}
然后在你的表格上你需要把这个
<<< ServiceInlineRow<Float>("PickerInlineRow") { (row : ServiceInlineRow<Float>) -> Void in
row.title = row.tag
row.value = 0
}
这是另一个带有滑块但带有字符串值的示例
public class CustomSliderInlineCell<T: Equatable> : Cell<T>, CellType {
required public init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
public override func setup() {
super.setup()
accessoryType = .None
editingAccessoryType = .None
}
public override func update() {
super.update()
selectionStyle = row.isDisabled ? .None : .Default
}
public override func didSelect() {
super.didSelect()
row.deselect()
}
}
//MARK: PickerInlineRow
public class _CustomSliderInlineRow<T where T: Equatable> : Row<T, CustomSliderInlineCell<T>>, NoValueDisplayTextConformance {
public typealias InlineRow = CustomSliderRow<T>
public var options = [T]()
public var noValueDisplayText: String?
required public init(tag: String?) {
super.init(tag: tag)
}
}
/// A generic inline row where the user can pick an option from a picker view
public final class CustomSliderInlineRow<T where T: Equatable> : _CustomSliderInlineRow<T>, RowType, InlineRowType {
required public init(tag: String?) {
super.init(tag: tag)
onExpandInlineRow { cell, row, _ in
let color = cell.detailTextLabel?.textColor
row.onCollapseInlineRow { cell, _, _ in
cell.detailTextLabel?.textColor = color
}
cell.detailTextLabel?.textColor = cell.tintColor
}
}
public override func customDidSelect() {
super.customDidSelect()
if !isDisabled {
toggleInlineRow()
}
}
public func setupInlineRow(inlineRow: InlineRow) {
inlineRow.values = options
inlineRow.displayValueFor = self.displayValueFor
}
}
以及 CustomSliderRow 和 Cell 的定义
public class CustomSliderCell<T: Equatable>: Cell<T>, CellType {
public required init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .Value1, reuseIdentifier: reuseIdentifier)
}
public var titleLabel: UILabel! {
textLabel?.translatesAutoresizingMaskIntoConstraints = false
textLabel?.setContentHuggingPriority(500, forAxis: .Horizontal)
return textLabel
}
public var valueLabel: UILabel! {
detailTextLabel?.translatesAutoresizingMaskIntoConstraints = false
detailTextLabel?.setContentHuggingPriority(500, forAxis: .Horizontal)
return detailTextLabel
}
lazy public var slider: UISlider = {
let result = UISlider()
result.translatesAutoresizingMaskIntoConstraints = false
result.setContentHuggingPriority(500, forAxis: .Horizontal)
return result
}()
public var formatter: NSNumberFormatter?
public override func setup() {
super.setup()
selectionStyle = .None
slider.minimumValue = sliderRow.minimumValue
slider.maximumValue = sliderRow.maximumValue
print(sliderRow.values.count)
slider.addTarget(self, action: #selector(CustomSliderCell.valueChanged), forControlEvents: .ValueChanged)
if shouldShowTitle() {
contentView.addSubview(titleLabel)
contentView.addSubview(valueLabel!)
}
contentView.addSubview(slider)
let views = ["titleLabel" : titleLabel, "valueLabel" : valueLabel, "slider" : slider]
let metrics = ["hPadding" : 16.0, "vPadding" : 12.0, "spacing" : 12.0]
if shouldShowTitle() {
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-hPadding-[titleLabel]-[valueLabel]-hPadding-|", options: NSLayoutFormatOptions.AlignAllBaseline, metrics: metrics, views: views))
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-vPadding-[titleLabel]-spacing-[slider]-vPadding-|", options: NSLayoutFormatOptions.AlignAllLeft, metrics: metrics, views: views))
} else {
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-vPadding-[slider]-vPadding-|", options: NSLayoutFormatOptions.AlignAllLeft, metrics: metrics, views: views))
}
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-hPadding-[slider]-hPadding-|", options: NSLayoutFormatOptions.AlignAllBaseline, metrics: metrics, views: views))
}
public override func update() {
super.update()
if !shouldShowTitle() {
textLabel?.text = nil
detailTextLabel?.text = nil
}
//slider.value = row.value ?? 0.0
slider.value = 0.0
}
func valueChanged() {
let roundedValue: Float
//let steps = Float(sliderRow.steps)
let steps = Float(sliderRow.values.count-1)
if steps > 0 {
let stepValue = round((slider.value - slider.minimumValue) / (slider.maximumValue - slider.minimumValue) * steps)
let stepAmount = (slider.maximumValue - slider.minimumValue) / steps
roundedValue = stepValue * stepAmount + self.slider.minimumValue
}
else {
roundedValue = slider.value
}
//row.value = roundedValue
row.value = sliderRow.values[Int(roundedValue)]
if shouldShowTitle() {
valueLabel.text = "\(row.value!)"
}
}
private func shouldShowTitle() -> Bool {
return row.title?.isEmpty == false
}
private var sliderRow: CustomSliderRow<T> {
return row as! CustomSliderRow
}
}
/// A row that displays a UISlider. If there is a title set then the title and value will appear above the UISlider.
public final class CustomSliderRow<T: Equatable>: Row<T, CustomSliderCell<T>>, RowType {
public var minimumValue: Float = 0.0
public var maximumValue: Float = 10.0
public var steps: UInt = 20
public var values : [T] = [T](){
willSet(newValues)
{
maximumValue = Float(newValues.count-1)
steps = UInt(newValues.count)
cell.setup()
}
}
required public init(tag: String?) {
super.init(tag: tag)
}
}
并且在您的表单中,您需要输入
<<< CustomSliderInlineRow<String>("CustomSliderRow"){ (row : CustomSliderInlineRow<String>) -> Void in
row.title = row.tag
row.options = ["Value1","Value2","Value3"]
row.value = "Value1"
}
希望对您有所帮助,问候