Есть ли способ добавить UIPickerView в UIAlertController (Alert или ActionSheet) в Swift?

Я совершенно новичок в Swift (и вообще в программировании iOS), но я начал возиться с этим (это было плохой идеей, когда все еще находится в бета-версии: D). Так что я пытался понять это сам, но все равно ничего. Даже пытался добавить подвид, содержащий сборщик, но безуспешно. Так может мне кто-нибудь помочь?


person Hristo Atanasov    schedule 28.08.2014    source источник
comment
Я успешно добавил элемент управления счетчиком в UIAlertController, вы также можете добавить UIPickerView с той же логикой, вот ссылка stackoverflow.com/questions/25652101/please-wait-dialog-in-ios8/   -  person Jageen    schedule 05.09.2014
comment
Это круто... Я видел это... Но я не могу проголосовать за твой ответ (нет репутации)   -  person Hristo Atanasov    schedule 05.09.2014
comment
размещаю ответ здесь, но он находится в Objective-C   -  person Jageen    schedule 05.09.2014
comment
В документах Apple говорится, что не следует создавать подкласс UIAlertController из-за сложности его внутренней иерархии представлений. Поэтому я думаю, что приведенные ниже ответы опасны. (И я не мог заставить их работать на меня.) См. этот другой вопрос, принятый ответ которого гласит следующее: in-ios8-not-working" title="отображение uipickerview с uiactionsheet в ios8 не работает"> stackoverflow.com/questions/24330152/   -  person webjprgm    schedule 06.12.2015
comment
Не вижу ничего опасного в ответах ниже. Я надеюсь, что iPhone не взорвется из-за модифицированного листа действий. И зачем мне создавать какой-то элемент, если уже есть тот, который я могу использовать. Apple по многим вещам говорит, что они придуманы не для того, что нужно разработчикам, но и не изобретают ничего полезного для своих нужд. Таким образом, весь Swift — это одна проблема, с которой нужно справиться. Я не могу представить ни одного серьезного прикладного проекта без использования каких-то хаков или трюков, если вы хотите сделать его таким, каким хотите. Все эти примеры работают нормально. Каждый может использовать его по доброй воле.. :)   -  person Hristo Atanasov    schedule 07.12.2015
comment
Документация Apple по UIAlertController явно предупреждает вас НЕ трогать иерархию представлений, что все эти ответы делают с alertcontroller.view.addSubview . Не делай этого, иначе потом будешь жалеть об этом   -  person xaphod    schedule 07.10.2016


Ответы (11)


Ну, это мой окончательный код, который сработал для меня. Это смесь нескольких идей. Основные причины, по которым я приму свой ответ, заключаются в том, что мой код написан на Swift, мой код использует UIAlertController, мой код предназначен для сборщика. Я хочу поблагодарить Джагина - мой ответ основан на его идее.

    func showPickerInActionSheet(sentBy: String) {
    var title = ""
    var message = "\n\n\n\n\n\n\n\n\n\n";
    var alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.ActionSheet);
    alert.modalInPopover = true;


    //Create a frame (placeholder/wrapper) for the picker and then create the picker
    var pickerFrame: CGRect = CGRectMake(17, 52, 270, 100); // CGRectMake(left), top, width, height) - left and top are like margins
    var picker: UIPickerView = UIPickerView(frame: pickerFrame);

    /* If there will be 2 or 3 pickers on this view, I am going to use the tag as a way
    to identify them in the delegate and datasource. /* This part with the tags is not required.
    I am doing it this way, because I have a variable, witch knows where the Alert has been invoked from.*/
    if(sentBy == "profile"){
        picker.tag = 1;
    } else if (sentBy == "user"){
        picker.tag = 2;
    } else {
        picker.tag = 0;
    }

    //set the pickers datasource and delegate
    picker.delegate = self;
    picker.dataSource = self;

    //Add the picker to the alert controller
    alert.view.addSubview(picker);

    //Create the toolbar view - the view witch will hold our 2 buttons 
    var toolFrame = CGRectMake(17, 5, 270, 45);
    var toolView: UIView = UIView(frame: toolFrame);

    //add buttons to the view
    var buttonCancelFrame: CGRect = CGRectMake(0, 7, 100, 30); //size & position of the button as placed on the toolView

    //Create the cancel button & set its title
    var buttonCancel: UIButton = UIButton(frame: buttonCancelFrame);
    buttonCancel.setTitle("Cancel", forState: UIControlState.Normal);
    buttonCancel.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal);
    toolView.addSubview(buttonCancel); //add it to the toolView

    //Add the target - target, function to call, the event witch will trigger the function call
    buttonCancel.addTarget(self, action: "cancelSelection:", forControlEvents: UIControlEvents.TouchDown);


    //add buttons to the view
    var buttonOkFrame: CGRect = CGRectMake(170, 7, 100, 30); //size & position of the button as placed on the toolView

    //Create the Select button & set the title
    var buttonOk: UIButton = UIButton(frame: buttonOkFrame);
    buttonOk.setTitle("Select", forState: UIControlState.Normal);
    buttonOk.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal);
    toolView.addSubview(buttonOk); //add to the subview

    //Add the tartget. In my case I dynamicly set the target of the select button
    if(sentBy == "profile"){
        buttonOk.addTarget(self, action: "saveProfile:", forControlEvents: UIControlEvents.TouchDown);
    } else if (sentBy == "user"){
        buttonOk.addTarget(self, action: "saveUser:", forControlEvents: UIControlEvents.TouchDown);
    }

    //add the toolbar to the alert controller
    alert.view.addSubview(toolView);

    self.presentViewController(alert, animated: true, completion: nil);
}

func saveProfile(sender: UIButton){
    // Your code when select button is tapped

}

func saveUser(sender: UIButton){
    // Your code when select button is tapped
}

func cancelSelection(sender: UIButton){
    println("Cancel");
    self.dismissViewControllerAnimated(true, completion: nil);
    // We dismiss the alert. Here you can add your additional code to execute when cancel is pressed
}

// returns number of rows in each component..
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
    if(pickerView.tag == 1){
        return self.profilesList.count;
    } else if(pickerView.tag == 2){
        return self.usersList.count;
    } else  {
        return 0;
    }
}

// Return the title of each row in your picker ... In my case that will be the profile name or the username string
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
    if(pickerView.tag == 1){

            var selectedProfile: Profiles = self.profilesList[row] as Profiles;
            return selectedProfile.profileName;

    } else if(pickerView.tag == 2){

            var selectedUser: Users = self.usersList[row] as Users;
            return selectedUser.username;

    } else  {

        return "";

    }

}

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if(pickerView.tag == 1){
            var choosenProfile: Profiles = profilesList[row] as Profiles;
            self.selectedProfile = choosenProfile.profileName;
    } else if (pickerView.tag == 2){
            var choosenUser: Profiles = usersList[row] as Users;
            self.selectedUsername = choosenUser.username;
    }

}
person Hristo Atanasov    schedule 25.11.2014
comment
Я использую тот же приведенный выше фрагмент, но мой PickerView не отображается. Новое в быстром программировании - person Terril Thomas; 25.02.2015
comment
Вы должны вызвать функцию showPickerInActionSheet(), чтобы отобразить PickerView. Вы можете вызвать его в функции @IBAction, привязанной к какой-либо кнопке или другому элементу, или в какой-либо обычной функции - person Hristo Atanasov; 26.02.2015
comment
Если с вашим кодом все в порядке, попробуйте поискать сообщение об ошибке/предупреждении в консоли (особенно если вы пытались отредактировать код). - person Hristo Atanasov; 26.02.2015
comment
Спасибо за ответ ... Я нашел проблему и решил ее - person Terril Thomas; 26.02.2015
comment
Если у кого-то еще есть проблемы, вам нужно установить UIAlertController в UIAlertControllerStyleAlert, а не в UIAlertControllerStyleActionSheet! - person PostCodeism; 24.03.2015
comment
Когда я нажимаю «Выбрать», ничего не происходит, даже если я устанавливаю функциональность в saveProfile. Любая помощь? - person Thiha Aung; 16.02.2016
comment
Этот ответ - все, что я хотел! Спасибо! - person Jayprakash Dubey; 29.07.2016

Попробуйте, я сделал кое-какой трюк...

Код ниже работает для меня в iPod iOS8beta5 + XCode6
Я добавляю элемент управления UIActivityIndicatorView в UIAlertController в target-c.

UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
                                        message:@"Please wait\n\n\n"
                                 preferredStyle:UIAlertControllerStyleAlert];

    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    spinner.center = CGPointMake(130.5, 65.5);
    spinner.color = [UIColor blackColor];
    [spinner startAnimating];
    [alert.view addSubview:spinner];
    [self presentViewController:alert animated:NO completion:nil];

введите здесь описание изображения


Примечание.
Это в target-c, но это доказывает, что мы можем сделать это и с помощью swift.

person Jageen    schedule 05.09.2014
comment
Поскольку UIAlertController является контроллером представления, вы также можете наследовать его и выполнять свои действия. - person Jageen; 05.09.2014

Вы можете использовать аналогичный код в iOS8/Swift, чтобы добавить свои собственные элементы управления в оповещение (вместо листа действий), которое появляется в середине экрана.

Единственная проблема, с которой я столкнулся при выполнении этого с помощью alert.addSubView, заключалась в том, что размер представления предупреждения зависит только от элементов управления, которые вы добавили с помощью методов класса. Затем вы должны добавить свои собственные ограничения, чтобы убедиться, что оповещение охватывает все ваши элементы управления.

Я добавил пример здесь, поскольку исходный вопрос задан для Alert или ActionSheet.

func addAlert(){

    // create the alert
    let title = "This is the title"
    let message = "This is the message"
    var alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert);
    alert.modalInPopover = true;

    // add an action button
    let nextAction: UIAlertAction = UIAlertAction(title: "Action", style: .Default){action->Void in
        // do something
    }
    alert.addAction(nextAction)

    // now create our custom view - we are using a container view which can contain other views
    let containerViewWidth = 250
    let containerViewHeight = 120
    var containerFrame = CGRectMake(10, 70, CGFloat(containerViewWidth), CGFloat(containerViewHeight));
    var containerView: UIView = UIView(frame: containerFrame);

    alert.view.addSubview(containerView)

    // now add some constraints to make sure that the alert resizes itself
    var cons:NSLayoutConstraint = NSLayoutConstraint(item: alert.view, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.GreaterThanOrEqual, toItem: containerView, attribute: NSLayoutAttribute.Height, multiplier: 1.00, constant: 130)

    alert.view.addConstraint(cons)

    var cons2:NSLayoutConstraint = NSLayoutConstraint(item: alert.view, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.GreaterThanOrEqual, toItem: containerView, attribute: NSLayoutAttribute.Width, multiplier: 1.00, constant: 20)

    alert.view.addConstraint(cons2)

    // present with our view controller
    presentViewController(alert, animated: true, completion: nil)

}
person leafcutter    schedule 18.12.2014
comment
Спасибо, этих ограничений мне не хватало...! - person beetree; 19.01.2015
comment
Отличная находка с ограничением - person Matt Rees; 09.07.2015

Мне нужно было сделать то же самое, и вот как я это решил. Я сделал что-то похожее на Джагина. Мой код ниже. Обратите внимание, что я помещаю значения в UIPickerView в другую часть кода.

//Need to use an UIAlertController for iOS 8 instead of an action view
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
                              message:@"\n\n\n\n\n\n\n\n"
                              preferredStyle:UIAlertControllerStyleAlert];

//Make a frame for the picker & then create the picker
CGRect pickerFrame = CGRectMake(0, 0, 270, 100);
UIPickerView *regionsPicker = [[UIPickerView alloc] initWithFrame:pickerFrame];

//There will be 3 pickers on this view so I am going to use the tag as a way
//to identify them in the delegate and datasource
regionsPicker.tag = 1;

//set the pickers datasource and delegate
regionsPicker.dataSource = self;
regionsPicker.delegate = self;

//set the pickers selection indicator to true so that the user will now which one that they are chosing
[regionsPicker setShowsSelectionIndicator:YES];

//Add the picker to the alert controller
[alert.view addSubview:regionsPicker];

//make the toolbar view
UIView *toolView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 270.0f, 44.f)];
toolView.backgroundColor = [UIColor blackColor]; //set it's background


//add buttons to the view
CGRect buttonFrame = CGRectMake(0, 5, 100, 30); //size & position of the button as placed on the toolView
//make the cancel button & set the title
UIButton *button = [[UIButton alloc] initWithFrame: buttonFrame];
[button setTitle: @"Cancel" forState: UIControlStateNormal];
[button setTitleColor: [UIColor blueColor] forState: UIControlStateNormal]; //make the color blue to keep the same look as prev version
[toolView addSubview:button]; //add to the subview

//Add the tartget
[button addTarget: self
           action: @selector(cancelRegionSet)
 forControlEvents: UIControlEventTouchDown];

//do the same for the select button
buttonFrame = CGRectMake(90, 5, 100, 30);
UIButton *selButton = [[UIButton alloc] initWithFrame:buttonFrame];
[selButton setTitle:@"Select" forState:UIControlStateNormal];
[selButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[toolView addSubview:selButton];

[selButton addTarget: self
              action: @selector(dismissRegionSet:)
 forControlEvents: UIControlEventTouchDown];

//add the toolbar to the alert controller
[alert.view addSubview:toolView];

[self presentViewController:alert animated:NO completion:nil];
person inosu812    schedule 08.09.2014

Swift 5.2/Xcode 11.6/iOS 11.4

func addAlert(){

    // create the alert
    let title = "This is the title"
    let message = "This is the message"
    let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert);
    alert.isModalInPopover = true;

    // add an action button
    let nextAction: UIAlertAction = UIAlertAction(title: "Action", style: .default){action->Void in
        // do something
    }
    alert.addAction(nextAction)

    // now create our custom view - we are using a container view which can contain other views
    let containerViewWidth = 250
    let containerViewHeight = 120
    let containerFrame = CGRect(x:10, y: 70, width: CGFloat(containerViewWidth), height: CGFloat(containerViewHeight));
    let containerView: UIView = UIView(frame: containerFrame);

    alert.view.addSubview(containerView)

    // now add some constraints to make sure that the alert resizes itself
    let cons:NSLayoutConstraint = NSLayoutConstraint(item: alert.view, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.greaterThanOrEqual, toItem: containerView, attribute: NSLayoutConstraint.Attribute.height, multiplier: 1.00, constant: 130)

    alert.view.addConstraint(cons)

    let cons2:NSLayoutConstraint = NSLayoutConstraint(item: alert.view, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.greaterThanOrEqual, toItem: containerView, attribute: NSLayoutConstraint.Attribute.width, multiplier: 1.00, constant: 20)

    alert.view.addConstraint(cons2)

    // present with our view controller
    present(alert, animated: true, completion: nil)

}
person drewster    schedule 28.06.2018

Я думаю, что это неплохая идея начать с бета-версии. Вам нужен пользовательский UIAlertView. Обратите внимание на UIAlertController, он доступен только в iOS 8.0.

Посмотрите здесь и здесь

person Max    schedule 28.08.2014
comment
Можете ли вы привести мне небольшой пример в Swift, потому что я не получил примеры в ваших ссылках (я думаю, это потому, что там слишком много ObjC;)) - person Hristo Atanasov; 28.08.2014
comment
Я думаю, вам следует начать с другой точки Swift, где вы узнаете, как это работает. Вы должны знать, как преобразовать код из obj-c в swift, потому что obj-c был основным языком iOS много времени, как вы знаете, и там была доступна некоторая информация, фреймворки, примеры obj-c, которые может помочь вам. - person Max; 28.08.2014
comment
Я думаю, что это большая проблема Apple. Они пытаются сделать очень медленный переход между объективным c и быстрым, заставляя xcode работать с обоими, чтобы облегчить программистам obc-c. А что делать людям, начинающим сейчас... им приходится учить 2 языка программирования, потому что свифт не может работать один без obj-c (большинство фреймворков в obj-c). Swift - это даже не язык, это закрытие для старого, старого, старого C и obj-c ... или Apple, просто заставьте меня почувствовать это ... Возьмем, например, Java, C #, PHP, даже javascript. .. все они могут выжить без использования какого-либо другого языка, так что .. - person Hristo Atanasov; 28.08.2014
comment
Спасибо за совет начать изучение Swift с другой точки... Но это совет для apple - начать создавать свифт с другой точки. Точка, где Свифт может работать автономно. Итак, Максим... Ваш первый комментарий мне понравился. Это подсказка для того, чтобы с чего-то начать... Я начинаю в этом направлении, но я подожду дальнейших объяснений... Не сердитесь... У меня даже нет репутации, чтобы выбрать лучший ответ или проголосовать за это так... Спокойно... ;) - person Hristo Atanasov; 28.08.2014
comment
Круто.. Наверное так же как и с болгарским и русским языками. Вы пишете по-русски, но я все равно понимаю, что вы имели в виду :) - person Hristo Atanasov; 28.08.2014
comment
Извиняюсь. У тебя русскоязычный никнейм :) - person Max; 28.08.2014
comment
Он болгарский... И я понял, что вы мне написали. - person Hristo Atanasov; 28.08.2014

Вы можете добавить Picker, например UIActionSheet в iOS 8, используя Objective-C:

 colorArray = [[NSMutableArray alloc ]initWithObjects:@"One", @"Two", @"Three", @"Four", @"Five", nil];
picker = [[UIPickerView alloc]init];
picker.frame = CGRectMake(0.0, 44.0,self.view.frame.size.width, 216.0);
picker.dataSource = self;
picker.delegate = self;
picker.showsSelectionIndicator = true;
picker.backgroundColor = [UIColor whiteColor];

UIToolbar* pickerDateToolbar = [[UIToolbar alloc] initWithFrame: CGRectMake(0, 0, 320, 44)];  //(frame: CGRectMake(0, 0, 320, 44))
pickerDateToolbar.barStyle =  UIBarStyleBlackTranslucent;//UIBarStyle.Black
pickerDateToolbar.barTintColor = [UIColor whiteColor];
pickerDateToolbar.translucent = true;
actionView.backgroundColor = [UIColor whiteColor];


UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(150, 5, 150, 20)];
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor blackColor];
label.shadowColor = [UIColor blackColor];
label.shadowOffset = CGSizeMake(0, 1);
label.font = [UIFont systemFontOfSize:15];//[UIFont boldSystemFontOfSize:15];
label.text = @"Select a Status";
UIBarButtonItem *labeltext= [[UIBarButtonItem alloc] initWithCustomView:label];


UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStylePlain target:self action:@selector(cancel_clicked:)];

UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(done_clicked:)];

pickerDateToolbar.items = [[NSArray alloc] initWithObjects:cancelBtn,flexSpace,labeltext,doneBtn,nil];

cancelBtn.tintColor = [UIColor blueColor];
doneBtn.tintColor = [UIColor blueColor];

[actionView addSubview:pickerDateToolbar];
[actionView addSubview:picker];

if (window != nil) {
[window addSubview:actionView];
}
else
{
[self.view addSubview:actionView];
}

[UIView animateWithDuration:(0.2) animations:^{
actionView.frame = CGRectMake(0, self.view.frame.size.height - 260.0, self.view.frame.size.width, 260.0);
self.view.alpha = 0.5;
actionView.alpha = 1;
}];

В ViewDidLoad добавьте это,

UIApplication * delegate = [UIApplication sharedApplication];
UIWindow *myWindow = delegate.keyWindow;
NSArray *myWindow2 = delegate.windows;

if(myWindow == [UIApplication sharedApplication].keyWindow)
window = myWindow;
else
window = myWindow2[0];

actionView = [[UIView alloc]initWithFrame:CGRectMake(0, UIScreen.mainScreen.bounds.size.height, UIScreen.mainScreen.bounds.size.width, 240.0)];

// Это для создания ActionView и для затемненного фона, когда средство выбора отображается во всплывающем окне.

-(void)cancel_clicked:(id)sender{
NSLog(@"cancel clicked");
[UIView animateWithDuration:0.2 animations:^{
actionView.frame = CGRectMake(0, UIScreen.mainScreen.bounds.size.height - 260.0, UIScreen.mainScreen.bounds.size.width, 260.0);
} completion:^(BOOL finished) {
self.view.alpha = 1;
[actionView removeFromSuperview];
}];

}

// Метод нажатия кнопки отмены.

-(void)done_clicked:(id)sender{
NSLog(@"done clicked");
self.view.userInteractionEnabled = TRUE;

[UIView animateWithDuration:0.2 animations:^{
actionView.frame = CGRectMake(0, UIScreen.mainScreen.bounds.size.height - 260.0, UIScreen.mainScreen.bounds.size.width, 260.0);
} completion:^(BOOL finished) {
_permitStatus.text = [colorArray objectAtIndex:[picker selectedRowInComponent:0]];
self.view.alpha = 1;
[actionView removeFromSuperview];
}];

}

// Для нажатия кнопки «Готово».

person Programming Learner    schedule 31.10.2014

Вот проект github, который выводит UIDatePicker в центре экрана. Он не использует UIAlertController или UIAlertView. Я не думаю, что это цель классов предупреждений.

person Gene De Lisa    schedule 29.08.2014
comment
Это интересное решение ... Немного сложное ... но я думаю, что это поможет :) - person Hristo Atanasov; 02.09.2014

Свифт 2.0:

Создайте образец представления выбора или представления сегмента и добавьте его в качестве подпредставления uialercontroller. Реализуйте делегатов uipickerview и представьте uialertcontroller. Вот как я добился того же.

class ViewController: 

    UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {

     var samplePicker: UIPickerView = UIPickerView()
     var sampleSegment:UISegmentedControl = UISegmentedControl ()
     var alertController:UIAlertController = UIAlertController()
     var buildings:[String] = ["BankBuilding", "Cinema" , "CornerShop", "Greg's House","14th Street"]

     override func viewDidLoad() {
      super.viewDidLoad()

      samplePicker = UIPickerView(frame: CGRectMake(10.0, 40.0, 250, 150))
      samplePicker.delegate =  self;
      samplePicker.dataSource = self;
      samplePicker.showsSelectionIndicator = true
      samplePicker.tintColor =  UIColor.redColor()
      samplePicker.reloadAllComponents()


      sampleSegment = UISegmentedControl(items: NSArray(object: "  Dismiss ") as [AnyObject])
      sampleSegment.momentary = true
      sampleSegment.frame = CGRectMake(25, 10.0, 100.0, 30.0)
      sampleSegment.tintColor = UIColor.blackColor()
      sampleSegment.backgroundColor = UIColor.orangeColor()
      sampleSegment.addTarget(self, action: "dismissAlert", forControlEvents: UIControlEvents.ValueChanged)

     }
     func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {

      return 1
     }

     func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
      return 3
     }

     func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

      return buildings[row] as String
     }

     func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
      print(buildings[0])

     }
     func pickerView(pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
      return 36.0
     }
     override func viewDidAppear(animated: Bool)
     {
      alertController = UIAlertController(title: " \n\n\n\n\n\n\n\n\n\n", message: "", preferredStyle: UIAlertControllerStyle.Alert)

      alertController.view.addSubview(sampleSegment)
      alertController.view.addSubview(samplePicker)

      self.presentViewController(alertController, animated: true, completion: nil)

     }
     func dismissAlert()
     {
      alertController.dismissViewControllerAnimated(true, completion: nil)
     }
     override func didReceiveMemoryWarning() {
      super.didReceiveMemoryWarning()

     }
    }
person A.G    schedule 02.03.2016

Свифт 3.0:

func showPickerInActionSheet() {

    let title = ""
    let message = "\n\n\n\n\n\n\n\n\n\n";
    let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.actionSheet);
    alert.isModalInPopover = true;


    //Create a frame (placeholder/wrapper) for the picker and then create the picker
    let pickerFrame = CGRect(x: 17, y: 52, width: 270, height: 100)
    let picker: UIPickerView = UIPickerView(frame: pickerFrame)


    //set the pickers datasource and delegate
    picker.delegate   = self
    picker.dataSource = self

    //Add the picker to the alert controller
    alert.view.addSubview(picker)

    //Create the toolbar view - the view witch will hold our 2 buttons
    let toolFrame = CGRect(x: 17, y: 5, width: 270, height: 45)
    let toolView: UIView = UIView(frame: toolFrame)


    //add buttons to the view
    let buttonCancelFrame = CGRect(x: 0, y: 7, width: 100, height: 30) //size & position of the button as placed on the toolView

    //Create the cancel button & set its title
    let buttonCancel: UIButton = UIButton(frame: buttonCancelFrame);
    buttonCancel.setTitle("Cancel", for: .normal)
    buttonCancel.setTitleColor(UIColor.blue, for: .normal)
    toolView.addSubview(buttonCancel); //add it to the toolView

    //Add the target - target, function to call, the event witch will trigger the function call
    buttonCancel.addTarget(self, action: Selector("cancelSelection:"), for: UIControlEvents.touchDown);


    //add buttons to the view

    let buttonOkFrame = CGRect(x: 170, y: 7, width: 100, height: 30)//size & position of the button as placed on the toolView

    //Create the Select button & set the title
    let buttonOk: UIButton = UIButton(frame: buttonOkFrame);
    buttonOk.setTitle("Select", for: UIControlState.normal);
    buttonOk.setTitleColor(UIColor.blue, for: UIControlState.normal);
    toolView.addSubview(buttonOk); //add to the subview

    buttonOk.addTarget(self, action: #selector(HomeViewController.saveDelayTime), for: UIControlEvents.touchDown);

    //add the toolbar to the alert controller
    alert.view.addSubview(toolView);

    self.present(alert, animated: true, completion: nil);
}

func saveProfile(sender: UIButton){
    // Your code when select button is tapped

}

func saveUser(sender: UIButton){
    // Your code when select button is tapped
}

func cancelSelection(sender: UIButton){
    self.dismiss(animated: true, completion: nil)

    // We dismiss the alert. Here you can add your additional code to execute when cancel is pressed
}

// returns number of rows in each component..
func numberOfComponents(in pickerView: UIPickerView) -> Int{
    return 1
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return 60
}

// Return the title of each row in your picker ... In my case that will be the profile name or the username string
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return "\(row)"

}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    selectedTime = row
}

func saveDelayTime() {
    self.dismiss(animated: true, completion: nil)
    UserDefaults.standard.set(selectedTime, forKey: "DelayTimeKey")
    let _ = UserDefaults.standard.synchronize()
}
person random    schedule 31.08.2017

Это предупреждение со средством выбора со статическим массивом значений средства выбора.

    func presentAlertWithPicker(title: String,
                             message: String,
                             pickerOptions: [String],
                             completion: @escaping ((_ pickerValueString: String) -> Void)){
        
        // Add a picker handler to provide the picker in the alert with the needed data
        class PickerHandler: NSObject, UIPickerViewDelegate, UIPickerViewDataSource{
            var items: [String]
            lazy var lastSelectedItem = items[0]
            
            init(items: [String]){
                self.items = items
                super.init()
            }

            func numberOfComponents(in pickerView: UIPickerView) -> Int {
                1
            }
            
            func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
                items.count
            }
            
            func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
                items[row]
            }
            
            func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
                print("selected item tag is \(pickerView.tag), row: \(row)")
                lastSelectedItem = items[row]
            }
        }
        
        DispatchQueue.main.async { [weak self] in
            let pickerHandler = PickerHandler(items: pickerOptions)
            let pickerView = UIPickerView(frame: .zero)
            pickerView.delegate = pickerHandler
            pickerView.dataSource = pickerHandler

            let title = title
            let message = message
            let alert = UIAlertController(title: title, message: message, preferredStyle: .alert);
            
            let selectAction = UIAlertAction(title: "Select", style: .default){action->Void in
                completion(pickerHandler.lastSelectedItem)
            }
            alert.addAction(selectAction)
            
            // Add the picker view
            alert.view.addSubview(pickerView)
            pickerView.translatesAutoresizingMaskIntoConstraints = false
            let constantAbovePicker: CGFloat = 70
            let constantBelowPicker: CGFloat = 50
            NSLayoutConstraint.activate([
                pickerView.leadingAnchor.constraint(equalTo: alert.view.leadingAnchor, constant:  10),
                pickerView.widthAnchor.constraint(equalToConstant: 250),
                pickerView.widthAnchor.constraint(lessThanOrEqualTo: alert.view.widthAnchor, constant: 20),

                pickerView.topAnchor.constraint(equalTo: alert.view.topAnchor, constant:  constantAbovePicker),
                pickerView.heightAnchor.constraint(equalToConstant: 150),
                alert.view.bottomAnchor.constraint(greaterThanOrEqualTo: pickerView.bottomAnchor, constant:  constantBelowPicker),
            ])

            self?.present(alert, animated: true, completion: nil)
        }
    }

Чтобы назвать это.

            presentAlertWithPicker(title: "This is the main title",
                                        message: "This is the main message",
                                        pickerOptions: ["1", "2", "3"]) { (pickerSelectedValue) in
                
                print(pickerSelectedValue)
            }
person M. Ali    schedule 10.02.2021