Eureka: How to create custom inline picker control with imageview

Created on 17 May 2016  路  8Comments  路  Source: xmartlabs/Eureka

I have read the doc about custom control creation, I wanted to create a custom PickerInlineRow control with a image preview, When we change the picker values and respective image should have to be appeared. see below.

screen shot 2016-05-17 at 7 07 09 pm

Could anyone please give your suggestion?

custom row question

All 8 comments

hmm.. i'm not a pro but try this :

On your picker, add :

.onChange { [weak self] row in
   let value = row.value // get the value selected
   print(value) 
   // switch here
   // change image in different case
}

I don't know how you create your picture so I can't help you to change :/

Actually we have json to load into the picker,

items:[
{
name:light,
price:$4.95
image: http://domain/path/image_light.jpg
}
]

But thing is here, how to add the imageView above the picker?

Thanks

@kbala You will have to create a custom row and its correspond cell that should contains the imageView and the picker (take PickerCell<T where T: Equatable> as a cell example to get started, which contains the pickerView but not the imageView).

Let's call this new row MyImageWithPickerRow<T where T: Equatable, T: TypeWithImage>. Whenever the picker view value changes it should update the image view, you can do this by conforming to picker view delegate from the row cell (again take a look at PickerCell<T> which conforms to the pickerView delegate and datasource).

Make your info data conforms to TypeWithImage and Equatable,this is to be able to use the row with any type that conforms to TypeWithImage and not just one type.

protocol TypeWithImage {
    var image: String { get  }
}

Make sure that the MyImageWithPickerRow<T> works as expected.

Then create the main row which will display the MyImageWithPickerRow InlineRow (note the typealias declaration below) when is tapped.

public final class PickerInlineRow<T where T: Equatable, T: TypeWithImage> : Row<T, PickerInlineCell<T>>, RowType, InlineRowType {

    public typealias InlineRow = MyImageWithPickerRow<T>
    public var options = [T]()
    required public init(tag: String?) {
        super.init(tag: tag)
        // ...
        // set up display value for to show the value accordingly
        // ...
        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.options = self.options
        inlineRow.displayValueFor = self.displayValueFor
    }
}

Thanks a lot @mtnbarreto, I will try this and let you know.

Question: I need to create custom ImageWithPickerCell as well?

@mtnbarreto please see my codes.

public protocol TypeWithImage {
    var image: String { get  }
}

public final class ImageWithPickerRow<T where T: Equatable, T:TypeWithImage>: _PickerRow<T>, RowType {

    required public init(tag: String?) {
        super.init(tag: tag)
    }
}

public final class ImageWithPickerInlineRow<T where T: Equatable, T: TypeWithImage> : Row<T, LabelCellOf<T>>, RowType, InlineRowType{

    public typealias InlineRow = ImageWithPickerRow<T>
    public var options = [T]()
    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.options = self.options
        inlineRow.displayValueFor = self.displayValueFor
    }
}

Implementation:

class ProductVariation : NSObject, TypeWithImage {
    var name:String = ""
    var price:Double = 0.0
    var image: String = ""
}

<<< ImageWithPickerInlineRow<ProductVariation>("Product") { (row : ImageWithPickerInlineRow<ProductVariation>) -> Void in

                row.title = row.tag
                row.displayValueFor = {
                    guard let pv = $0 else{
                        return nil
                    }
                    return "\(pv.name) ------- $\(pv.price)"
                }



                row.options = []
                let pv = ProductVariation()
                pv.name = "Light"
                pv.price = 4.5
                pv.image = "http://s7d2.scene7.com/is/image/Drugstore/201915?wid=220&hei=220&op_sharpen=1"

                let pv1 = ProductVariation()
                pv1.name = "Golden"
                pv1.price = 9.5
                pv1.image = "http://s7d2.scene7.com/is/image/Drugstore/201915?wid=220&hei=220&op_sharpen=1"

                row.options.append(pv)
                row.options.append(pv1)


                row.value = row.options[0]
        }

One thing i am not sure here where to add the ImageView Object, Please help

Thanks

As you said you will need a ImageWithPickerCell cell.

ImageWithPickerRow should not extend from _PickerRow since _PickerRow uses PickerCell<T> as cell type and we need a custom cell (ImageWithPickerCell) to display the imageView in addition to the picker view..


public final class ImageWithPickerRow<T where T: Equatable, T:TypeWithImage>: Row<T, ImageWithPickerCell<T>>, RowType {

    public var options = [T]()

    required public init(tag: String?) {
        super.init(tag: tag)
    }
}

@kbala Could you implement this picker row? Can we close the issue?

Was this page helpful?
0 / 5 - 0 ratings