UIPickerView programmatic example?

后端 未结 4 998
旧时难觅i
旧时难觅i 2020-12-02 19:45

How do I programmatically setup up the UIPickerView in a view without using Interface Builder? Also having trouble understanding how to work with the delegate portions of t

相关标签:
4条回答
  • 2020-12-02 20:31

    Here is the class i have created recently. Its in swift 4.1.2. Just write one line and you picker will be on display.

    import UIKit
    class CustomPickerView:NSObject,UIPickerViewDelegate,UIPickerViewDataSource{
    
    
        //Theme colors
        var itemTextColor = UIColor.black
        var backgroundColor = UIColor.orange.withAlphaComponent(0.5)
        var toolBarColor = UIColor.blue
        var font = UIFont.systemFont(ofSize: 16)
    
        private static var shared:CustomPickerView!
        var bottomAnchorOfPickerView:NSLayoutConstraint!
        var heightOfPickerView:CGFloat = UIDevice.current.userInterfaceIdiom == .pad ? 160 : 120
        var heightOfToolbar:CGFloat = UIDevice.current.userInterfaceIdiom == .pad ? 50 : 40
    
        var dataSource:(items:[String]?,itemIds:[String]?)
    
        typealias CompletionBlock = (_ item:String?,_ id:String?) -> Void
        var didSelectCompletion:CompletionBlock?
        var doneBottonCompletion:CompletionBlock?
        var cancelBottonCompletion:CompletionBlock?
    
    
        lazy var pickerView:UIPickerView={
            let pv = UIPickerView()
            pv.translatesAutoresizingMaskIntoConstraints = false
            pv.delegate = self
            pv.dataSource = self
            pv.showsSelectionIndicator = true
            pv.backgroundColor = self.backgroundColor
            return pv
        }()
    
        lazy var disablerView:UIView={
            let view = UIView()
            view.backgroundColor = UIColor.black.withAlphaComponent(0.1)
            view.translatesAutoresizingMaskIntoConstraints = false
            view.alpha = 0
            return view
        }()
    
        lazy var tooBar:UIView={
            let view = UIView()
            view.backgroundColor = self.toolBarColor
            view.translatesAutoresizingMaskIntoConstraints = false
    
            view.addSubview(buttonDone)
            buttonDone.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true
            buttonDone.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
            buttonDone.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
            buttonDone.widthAnchor.constraint(equalToConstant: 65).isActive = true
    
            view.addSubview(buttonCancel)
            buttonCancel.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
            buttonCancel.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
            buttonCancel.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
            buttonCancel.widthAnchor.constraint(equalToConstant: 65).isActive = true
    
            return view
        }()
    
    
        lazy var buttonDone:UIButton={
            let button = UIButton(type: .system)
            button.setTitle("Done", for: .normal)
            button.tintColor = self.itemTextColor
            button.titleLabel?.font = self.font
            button.translatesAutoresizingMaskIntoConstraints = false
            button.titleLabel?.adjustsFontSizeToFitWidth = true
            button.addTarget(self, action: #selector(self.buttonDoneClicked), for: .touchUpInside)
            return button
        }()
    
        lazy var buttonCancel:UIButton={
            let button = UIButton(type: .system)
            button.setTitle("Cancel", for: .normal)
            button.tintColor = self.itemTextColor
            button.titleLabel?.font = self.font
            button.translatesAutoresizingMaskIntoConstraints = false
            button.titleLabel?.adjustsFontSizeToFitWidth = true
            button.addTarget(self, action: #selector(self.buttonCancelClicked), for: .touchUpInside)
            return button
        }()
    
    
        static func show(items:[String],itemIds:[String]? = nil,selectedValue:String? = nil,doneBottonCompletion:CompletionBlock?,didSelectCompletion:CompletionBlock?,cancelBottonCompletion:CompletionBlock?){
    
            if CustomPickerView.shared == nil{
                shared = CustomPickerView()
            }else{
                return
            }
    
            if let appDelegate = UIApplication.shared.delegate as? AppDelegate,let keyWindow = appDelegate.window {
    
                shared.cancelBottonCompletion = cancelBottonCompletion
                shared.didSelectCompletion = didSelectCompletion
                shared.doneBottonCompletion = doneBottonCompletion
                shared.dataSource.items = items
    
                if let idsVal = itemIds,items.count == idsVal.count{ //ids can not be less or more than items
                    shared?.dataSource.itemIds  = itemIds
                }
    
                shared?.heightOfPickerView += shared.heightOfToolbar
    
                keyWindow.addSubview(shared.disablerView)
                shared.disablerView.leftAnchor.constraint(equalTo: keyWindow.leftAnchor, constant: 0).isActive = true
                shared.disablerView.rightAnchor.constraint(equalTo: keyWindow.rightAnchor, constant: 0).isActive = true
                shared.disablerView.topAnchor.constraint(equalTo: keyWindow.topAnchor, constant: 0).isActive = true
                shared.disablerView.bottomAnchor.constraint(equalTo: keyWindow.bottomAnchor, constant: 0).isActive = true
    
    
                shared.disablerView.addSubview(shared.pickerView)
                shared.pickerView.leftAnchor.constraint(equalTo: shared.disablerView.leftAnchor, constant: 0).isActive = true
                shared.pickerView.rightAnchor.constraint(equalTo: shared.disablerView.rightAnchor, constant: 0).isActive = true
                shared.pickerView.heightAnchor.constraint(equalToConstant: shared.heightOfPickerView).isActive = true
                shared.bottomAnchorOfPickerView = shared.pickerView.topAnchor.constraint(equalTo: shared.disablerView.bottomAnchor, constant: 0)
                shared.bottomAnchorOfPickerView.isActive = true
    
    
                shared.disablerView.addSubview(shared.tooBar)
                shared.tooBar.heightAnchor.constraint(equalToConstant: shared.heightOfToolbar).isActive = true
                shared.tooBar.leftAnchor.constraint(equalTo: shared.disablerView.leftAnchor, constant: 0).isActive = true
                shared.tooBar.rightAnchor.constraint(equalTo: shared.disablerView.rightAnchor, constant: 0).isActive = true
                shared.tooBar.bottomAnchor.constraint(equalTo: shared.pickerView.topAnchor, constant: 0).isActive = true
    
                keyWindow.layoutIfNeeded()
    
    
                if let selectedVal = selectedValue{
                    for (index,itemName) in items.enumerated(){
                        if itemName.lowercased() == selectedVal.lowercased(){
                            shared.pickerView.selectRow(index, inComponent: 0, animated: false)
                            break
                        }
                    }
                }
    
                shared.bottomAnchorOfPickerView.constant = -shared.heightOfPickerView
    
                UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
                    keyWindow.layoutIfNeeded()
                    shared.disablerView.alpha = 1
                }) { (bool) in  }
    
            }
        }
    
    
        //MARK: Picker datasource delegates
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 1
        }
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            if let count = dataSource.items?.count{
                return count
            }
            return 0
        }
    
    
    
        //MARK: Picker delegates
        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?{
            if let names = dataSource.items{
                return names[row]
            }
            return nil
        }
    
        func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
            if let names = dataSource.items{
                let item = names[row]
                return NSAttributedString(string: item, attributes: [NSAttributedStringKey.foregroundColor : itemTextColor,NSAttributedStringKey.font : font])
            }
            return nil
        }
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            var itemName:String?
            var id:String?
    
            if let names = dataSource.items{
                itemName = names[row]
            }
            if let ids = dataSource.itemIds{
                id = ids[row]
            }
            self.didSelectCompletion?(itemName, id)
        }
    
    
    
        @objc func buttonDoneClicked(){
            self.hidePicker(handler: doneBottonCompletion)
        }
    
        @objc func buttonCancelClicked(){
    
            self.hidePicker(handler: cancelBottonCompletion)
        }
    
        func hidePicker(handler:CompletionBlock?){
            var itemName:String?
            var id:String?
            let row = self.pickerView.selectedRow(inComponent: 0)
            if let names = dataSource.items{
                itemName = names[row]
            }
            if let ids = dataSource.itemIds{
                id = ids[row]
            }
            handler?(itemName, id)
    
            bottomAnchorOfPickerView.constant = self.heightOfPickerView
            UIView.animate(withDuration: 0.7, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
                self.disablerView.window!.layoutIfNeeded()
                self.disablerView.alpha = 0
            }) { (bool) in
                self.disablerView.removeFromSuperview()
                CustomPickerView.shared = nil
            }
        }
    
    }
    

    You can use it anywhere, see example below.

     CustomPickerView.show(items: ["item1","item2","item3"],itemIds: ["id1","id2","id3"],selectedValue:"item3", doneBottonCompletion: { (item, index) in
                print("done",item,index)
            }, didSelectCompletion: { (item, index) in
                print("selection",item,index)
            }) { (item, index) in
                print("cancelled",item,index)
            }
    
    0 讨论(0)
  • 2020-12-02 20:35

    This will not work in iOS 8

    Create UIPickerView programmatically with DataSource

    .h file

    @interface PickerViewTestAppViewController : UIViewController<UIPickerViewDelegate, UIPickerViewDataSource> {
         UIActionSheet *pickerViewPopup;
         UIPickerView *categoryPickerView;
         UIPickerView *pickerView;
         NSMutableArray *dataArray;
    }
    
    @property (nonatomic, retain) UIActionSheet *pickerViewPopup;
    @property (nonatomic, retain) UIPickerView *categoryPickerView;
    @property (nonatomic, retain) NSMutableArray *dataArray;
    
    @end
    

    .m file

    @implementation PickerViewTestAppViewController
    
    @synthesize pickerViewPopup,categoryPickerView;
    @synthesize dataArray;
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
     // Init the data array.
     dataArray = [[NSMutableArray alloc] init];
    
     // Add some data for demo purposes.
     [dataArray addObject:@"One"];
     [dataArray addObject:@"Two"];
     [dataArray addObject:@"Three"];
     [dataArray addObject:@"Four"];
     [dataArray addObject:@"Five"];
    
     pickerViewPopup = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
    
     categoryPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 44, 0, 0)];
    
    [categoryPickerView setDataSource: self];
    [categoryPickerView setDelegate: self];
    categoryPickerView.showsSelectionIndicator = YES;
    
        UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
        pickerToolbar.barStyle = UIBarStyleBlackOpaque;
        [pickerToolbar sizeToFit];
    
        UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
    
        UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(categoryDoneButtonPressed)];
    
        UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(categoryCancelButtonPressed)];
    
        [pickerToolbar setItems:@[cancelBtn, flexSpace, doneBtn] animated:YES];
    
        [pickerViewPopup addSubview:pickerToolbar];
        [pickerViewPopup addSubview:categoryPickerView];
        [pickerViewPopup showInView:self.view];
        [pickerViewPopup setBounds:CGRectMake(0,0,320, 464)];
    }
    
    - (void)pickerView:(UIPickerView *)pickerView didSelectRow: (NSInteger)row inComponent:(NSInteger)component {
    // Handle the selection
    
    NSLog(@"%@",[dataArray objectAtIndex:row]);       
    selectedCategory = [NSString stringWithFormat:@"%@",[dataArray objectAtIndex:row]];
    }
    // tell the picker how many rows are available for a given component
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
        return [dataArray count];
    }
    
    // tell the picker how many components it will have
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
        return 1;
    }
    
    // tell the picker the title for a given component
    - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    
        return [dataArray objectAtIndex: row];
    
    }
    
    // tell the picker the width of each row for a given component
    - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
        int sectionWidth = 300;
    
        return sectionWidth;
    }
    
    -(void)categoryDoneButtonPressed{
    categoryLable.text = selectedCategory;
    [pickerViewPopup dismissWithClickedButtonIndex:1 animated:YES];
    }
    
    -(void)categoryCancelButtonPressed{
        [pickerViewPopup dismissWithClickedButtonIndex:1 animated:YES];
    }
    

    Ref: http://gabriel-tips.blogspot.in/2011/04/uipickerview-add-it-programmatically_04.html

    0 讨论(0)
  • 2020-12-02 20:35
     NSInteger selectCourse=[_coursePicker selectedRowInComponent:0];
        NSInteger selectSem=[_coursePicker selectedRowInComponent:1];
        NSString *whatCourse=[Course objectAtIndex:selectCourse];
        NSString *whatSem=[Sem objectAtIndex:selectSem];
    
        NSString *courses=[[NSString alloc]initWithFormat:@"Course : %@ - %@",whatCourse,whatSem];
    
        [self.selectedCours setTitle:courses forState:UIControlStateNormal];
    
    0 讨论(0)
  • 2020-12-02 20:49

    To add UIPickerView programmatically:

    - (void)pickerView:(UIPickerView *)pV didSelectRow:(NSInteger)row inComponent:(NSInteger)component
    {
        if(component == 1)
            selectedRowPicker1 = row;
        else if(component == 2)
            selectedRowPicker2 = row;
        else
            selectedRowPicker3 = row;
    }
    
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
    {
        return 3;
    }
    
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
    { 
        if(component == 1)
            return [list1 count];
        else if(component == 2)
            return [list2 count];
        else
            return [list3 count];
    }
    
    - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
    {
        if(component == 1)
            val1 = [list1 objectAtIndex:row];
        else if(component == 2)
            val2 = [list2 objectAtIndex:row];
        else
            val3 = [list3 objectAtIndex:row];
    
        return strTemp;
    }
    
    0 讨论(0)
提交回复
热议问题