如何使用 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"
        }

希望对您有所帮助,问候