Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

About customizing row height for RxPickerViewViewAdapter. #423

Open
HowsonLiu opened this issue Mar 11, 2023 · 0 comments
Open

About customizing row height for RxPickerViewViewAdapter. #423

HowsonLiu opened this issue Mar 11, 2023 · 0 comments

Comments

@HowsonLiu
Copy link

lazy var pickerAdapter: RxPickerViewViewAdapter<Array<Any>> = {
        return RxPickerViewViewAdapter<Array<Any>>(components: [],
                                                   numberOfComponents: { _,_,_ in 1 },
                                                   numberOfRowsInComponent: { _,_,items,_ in items.count},
                                                   viewForRow: { [weak self] _,_,items,row,_,_ -> UIView in
            let label = Label(text: "\(items[row])")
            label.font = self?.pickerFont
            if self?.pickerAxis == .horizontal {
                label.transform = CGAffineTransform(rotationAngle: .pi / 2)
            }
            return label
        })
    }()

Observable.just(pickerItems)
                .bind(to: pickerView.rx.items(adapter: pickerAdapter))
                .disposed(by: pickerDisposeBag)

I would like to set the height of the label to 100. I see that RxPickerViewViewAdapter inherits from UIPickerViewDelegate.However, there is no handling of rowHeightForComponent in RxPickerViewViewAdapter. I tried adding an extension to RxPickerViewViewAdapter

extension RxPickerViewViewAdapter {
   public func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return 100
    }
}

or subclassing it and overriding the rowHeightForComponent method.

open class RxPickerViewHeightViewAdapter<Components>: RxPickerViewViewAdapter<Components> {
    
    public typealias HeightOfRowsInComponent = (
        _ dataSource: RxPickerViewHeightViewAdapter<Components>,
        _ pickerView: UIPickerView,
        _ components: Components,
        _ component: Int
    ) -> CGFloat
    
    private let heightOfRowsInComponent: HeightOfRowsInComponent
    
    fileprivate var components: Components
    
    public init(components: Components,
                numberOfComponents: @escaping NumberOfComponents,
                numberOfRowsInComponent: @escaping NumberOfRowsInComponent,
                viewForRow: @escaping ViewForRow,
                heightOfRowsInComponent: @escaping HeightOfRowsInComponent) {
        self.components = components
        self.heightOfRowsInComponent = heightOfRowsInComponent
        super.init(components: components,
                   numberOfComponents: numberOfComponents,
                   numberOfRowsInComponent: numberOfRowsInComponent,
                   viewForRow: viewForRow)
    }
    
    open func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return self.heightOfRowsInComponent(self, pickerView, components, component)
    }   
}

but they both didn't work
In the end, I modified the source code of RxPickerViewViewAdapter

open class RxPickerViewViewAdapter<Components>: RxPickerViewDataSource<Components>, UIPickerViewDelegate {
    /**
     - parameter dataSource
     - parameter pickerView
     - parameter components
     - parameter row
     - parameter component
     - parameter view
    */
    public typealias ViewForRow = (
        _ dataSource: RxPickerViewViewAdapter<Components>,
        _ pickerView: UIPickerView,
        _ components: Components,
        _ row: Int,
        _ component: Int,
        _ view: UIView?
    ) -> UIView
    
    private let viewForRow: ViewForRow
    
    /**
     - parameter dataSource
     - parameter pickerView
     - parameter components
     - parameter component
    */
    public typealias RowHeightForComponent = (
        _ dataSource: RxPickerViewViewAdapter<Components>,
        _ pickerView: UIPickerView,
        _ components: Components,
        _ component: Int
    ) -> CGFloat
    
    private let rowHeightForComponent: RowHeightForComponent

    /**
     - parameter components: Initial content value.
     - parameter numberOfComponents: Implementation of corresponding delegate method.
     - parameter numberOfRowsInComponent: Implementation of corresponding delegate method.
     - parameter viewForRow: Implementation of corresponding adapter method that converts component to `UIView`.
     */
    public init(components: Components,
                numberOfComponents: @escaping NumberOfComponents,
                numberOfRowsInComponent: @escaping NumberOfRowsInComponent,
                rowHeightForComponent: @escaping RowHeightForComponent,
                viewForRow: @escaping ViewForRow) {
        self.viewForRow = viewForRow
        self.rowHeightForComponent = rowHeightForComponent
        super.init(components: components,
                   numberOfComponents: numberOfComponents,
                   numberOfRowsInComponent: numberOfRowsInComponent)
    }
    
    open func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        return viewForRow(self, pickerView, components, row, component, view)
    }
    
    open func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return rowHeightForComponent(self, pickerView, components, component)
    }
}

and it worked
so are there any better solutions about this question? should i submit a mr?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant