如何使用 Eureka 创建自定义内联行?

Posted

技术标签:

【中文标题】如何使用 Eureka 创建自定义内联行?【英文标题】:How to create custom inline rows with Eureka? 【发布时间】:2016-06-11 19:36:58 【问题描述】:

我想用 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,但我找不到原因。

【问题讨论】:

【参考方案1】:

您好,我一直在处理您的问题,这是我的结果,看起来是这样的

我将发布两个使用 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 创建自定义内联行?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Angular 6 中的自定义指令来呈现动态生成的内联 SVG

如何在 JavaScript 中“正确”创建自定义对象?

如何在 django admin 中自定义多对多内联模型

如何使用 Eureka 框架根据所选值隐藏行/部分

在 Eureka 中向自定义规则添加规则

集合类型内联模板