问题描述
我想用Eureka实现自定义内联
单元格
,如描述
我将发布两个带有eureka的自定义内联行的示例
第一个示例是带滑块的自定义内联行,其值为0..100
公共类ServiceInlineCell< T:Equatable> :Cell< T>,CellType {
需要公共init(样式: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?
必需public init(tag:String?){
super.init(tag:tag)
}
}
// /一个通用的内联行,用户可以从选择器视图中选择一个选项
公共最终类ServiceInlineRow< T其中T:Equatable> :_ServiceInlineRow,RowType,InlineRowType {
必需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>) - >无效
row.title = row.tag
row.value = 0
}
这是滑块但带字符串值的另一个例子
public class CustomSliderInlineCell< T:Equatable> :Cell< T>,CellType {
需要公共init(样式: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
公共类_CustomSliderInlineRow< T其中T:Equatable> :Row< T,CustomSliderInlineCell< T>>,NoValueDisplayTextConformance {
public typealias InlineRow = CustomSliderRow< T>
public var options = [T]()
public var noValueDisplayText:String?
必需public init(tag:String?){
super.init(tag:tag)
}
}
// /一个通用的内联行,用户可以从选择器视图中选择一个选项
公共最终类CustomSliderInlineRow< T其中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
公共类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)
返回结果
}()
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.A lignAllBaseline,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)
如果步骤> 0 {
让stepValue = round((slider.value - slider.minimumValue)/(slider.maximumValue - slider.minimumValue)*步骤)
让stepAmount =(slider.maximumValue - slider.minimumValue)/步骤
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> {
返回行! CustomSliderRow
}
}
///显示UISlider的行。如果有标题集,则标题和值将显示在UISlider上方。
公共最终类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>) - >无效
row.title = row.tag
row.options = [Value1,Value2,Value3]
row.value =Value1
}
我希望这可以帮到你,问候
I would like implement a custom inline
cell
with Eureka like described here. But I have some problems to make in compile in my concrete case. Swift compiler crashes when I try to run with the following error.
...
Call parameter type does not match function signature!
...
1. Running pass 'Module Verifier' on function'@_TWaC7TonyPro22ServiceCheckInlineRow26Eureka13InlineRowTypeS_'
...
My collapsable Row and Cell.
public final class ServiceRow: Row<Service, ServiceCell>, RowType {
...
}
public class ServiceCell: Cell<Service>, CellType {
...
}
My inline row
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
}
}
I assume that the origin of the problem is the aliasType InlineRow
but I do not find why.
Hello I had been working on your question and this are my results, this is how looks
I will post two examples of custom inline rows with eureka
First example is a custom inline row with slider with values from 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)"
}
}
}
and then on your form you need to put this
<<< ServiceInlineRow<Float>("PickerInlineRow") { (row : ServiceInlineRow<Float>) -> Void in
row.title = row.tag
row.value = 0
}
And this is another example with an slider but with string values
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
}
}
And the definition for CustomSliderRow and 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)
}
}
And in your form you need to put
<<< CustomSliderInlineRow<String>("CustomSliderRow"){ (row : CustomSliderInlineRow<String>) -> Void in
row.title = row.tag
row.options = ["Value1","Value2","Value3"]
row.value = "Value1"
}
I hope this helps you, regards
这篇关于如何使用Eureka创建自定义内联行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!