有没有办法将UIPickerView添加到Swift中的UIAlertController(Alert或ActionSheet)?

我对swift(以及iOS编程)完全陌生,但是我开始搞乱它(当所有东西都是beta版时,这不是一个好主意:D)。 所以我试图自己弄清楚,但还是一无所获。 甚至试图添加包含select器的子视图没有任何成功。 那么,任何人都可以帮助我吗?

那么这是我最后的代码,为我工作。 这是几个想法的混合。 我接受我的答案的主要原因是我的代码是在Swift中,我的代码使用UIAlertController,我的代码是用于select器。 我要感谢杰根 – 我的回答是基于他的想法。

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; } } 

试试这个我做了一些伎俩…

下面的代码在iPod iOS8beta5 + XCode6中为我工作
我在UIAlertController的objective-c中添加UIActivityIndi​​catorView控件。

 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]; 

在这里输入图像说明


注意 :
这是在objective-c中,但是这certificate我们也可以用swift来做到这一点。

您可以在iOS8 / Swift中使用类似的代码将自己的控件添加到屏幕中间popup的警报(而不是操作页)中。

我用alert.addSubView做这件事的唯一问题是,alert视图只根据您通过类方法添加的控件来自行resize。 您必须添加自己的约束,以确保警报包含所有控件。

我在这里添加了一个例子,因为原来的问题要求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) } 

我需要做同样的事情,这就是我解决这个问题的方法。 我做了类似Jageen的事情。 我的代码如下。 请注意,我把值放在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]; 

我认为从beta版开始并不是个坏主意。 你需要自定义的UIAlertView 。 注意UIAlertController 只能在iOS 8.0中使用。

看那里和那里

 alertController = [UIAlertController alertControllerWithTitle:@" \n\n\n\n\n\n\n\n\n\n" message:@"" preferredStyle:UIAlertControllerStyleActionSheet]; closePicker = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:@"Cancel"]]; closePicker.momentary = YES; closePicker.frame = CGRectMake(25, 0.0f, 50.0f, 30.0f); closePicker.segmentedControlStyle = UISegmentedControlStyleBar; closePicker.tintColor = [UIColor blackColor]; [closePicker addTarget:self action:@selector(dismissActionSheet:) forControlEvents:UIControlEventValueChanged]; [alertController.view addSubview:closePicker]; UIPickerView *pickerFiliter=[[UIPickerView alloc]init]; pickerFiliter = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320.0, 120.0)]; pickerFiliter.showsSelectionIndicator = YES; pickerFiliter.dataSource = self; pickerFiliter.delegate = self; [alertController.view addSubview:pickerFiliter]; [self presentViewController:alertController animated:YES completion:nil]; - (IBAction)dismissActionSheet:(id)sender { [alertController dismissViewControllerAnimated:YES completion:nil]; } 

您可以使用Objective-C在iOS 8中添加像UIActionSheet这样的Picker:

  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)]; 

//这是为了在popup窗口中显示select器时创buildActionView和褪色的背景。

 -(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]; }]; 

}

//取消button单击方法。

 -(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]; }]; 

}

//完成button单击。

这是一个github项目 ,在屏幕的中心popup一个UIDatePicker。 它不使用UIAlertController或UIAlertView。 我不认为这是警报类的意图。

Swift 2.0:

做一个示例pickerview或段视图,并将其添加为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() } } 

Swift 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() }