Affichage d'un UIPickerView
avec UIActionSheet
dans iOS8 ne fonctionne pas
Le code fonctionne dans iOS7 , mais il ne fonctionne pas dans iOS8 . Je suis sûr que c'est parce que UIActionSheet est déconseillé dans iOS8 et Apple recommande d'utiliser UIAlertController
.
Cependant, comment le faire dans iOS8 ? Je devrais utiliser UIAlertController
?
iOS7 :
iOS8 :
MODIFIER:
De la référence pour UIActionSheet:
UIActionSheet n'est pas conçu pour être sous-classé, et vous ne devez pas ajouter de vues à sa hiérarchie. Si vous devez présenter une feuille avec plus de personnalisation que celle fournie par l'API UIActionSheet, vous pouvez créer la vôtre et la présenter de manière modale avec presentViewController: animated: complétion :.
Je suppose que vous voyez exactement pourquoi.
La référence pour UIAlertController n'a pas de clause de non-responsabilité similaire, mais en regardant son interface, je suppose que Apple l'ajoutera avant la sortie.
Ma recommandation serait de simplement créer une petite vue contenant votre sélecteur et vos boutons et de l'afficher et de la masquer si nécessaire. Ce n'est pas si difficile à faire et vous ne poussez pas les interfaces au-delà de leurs utilisations prévues.
Pour obtenir le même effet visuel, vous pouvez utiliser ActionSheetPicker-3., qui fonctionne avec iOS 8 .
En fait, ce n'est plus UIActionSheet
. Mais c'est exactement la même chose, et c'est pourquoi cela fonctionne sur iOS 8 .
UIActionSheet est déprécié dans iOS8 . Utilisez UIAlertController pour iOS8 ou version ultérieure
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"My Alert"
message:@"This is an action shhet."
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* cameraAction = [UIAlertAction actionWithTitle:@"Take A Photo" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
UIAlertAction* galleryAction = [UIAlertAction actionWithTitle:@"From Gallery" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
UIAlertAction * defaultAct = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {}];
[alert addAction:cameraAction];
[alert addAction:galleryAction];
[alert addAction:defaultAct];
[self presentViewController:alert animated:YES completion:nil];
Réf: IAlertController
J'écris le sélecteur de temps par moi-même à la place UIActionSheet dans iOS8:
date = [NSDate date];
timePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 44, 0, 0)];
timePicker.datePickerMode = UIDatePickerModeDateAndTime;
timePicker.hidden = NO;
timePicker.date = date;
displayFormatter = [[NSDateFormatter alloc] init];
[displayFormatter setTimeZone:[NSTimeZone localTimeZone]];
[displayFormatter setDateFormat:@"MM月dd日 EEE HH:mm"];
formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone localTimeZone]];
[formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
startDisplayTimeString = [displayFormatter stringFromDate:timePicker.date];
startTimeString = [formatter stringFromDate:timePicker.date];
NSTimeInterval interval = 24*60*60*1;
NSDate *endDate = [[NSDate alloc] initWithTimeIntervalSinceNow:interval];
endDisplayTimeString = [displayFormatter stringFromDate:endDate];
endTimeString = [formatter stringFromDate:endDate];
[_startTimeLabel setText:startDisplayTimeString];
[_endTimeLabel setText:endDisplayTimeString];
[pickerViewPopup dismissWithClickedButtonIndex:1 animated:YES];
NSDateFormatter *dateFormatter =[[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 64)];
pickerToolbar.tintColor = [UIColor whiteColor];
[pickerToolbar sizeToFit];
UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:self action:@selector(cancelBtnPressed:)];
[cancelBtn setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor colorWithRed:253.0/255.0 green:68.0/255.0 blue:142.0/255.0 alpha:1.0],
NSForegroundColorAttributeName,
nil] forState:UIControlStateNormal];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *titleButton;
float pickerMarginHeight = 168;
titleButton = [[UIBarButtonItem alloc] initWithTitle:@"title" style:UIBarButtonItemStylePlain target: nil action: nil];
[titleButton setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor colorWithRed:253.0/255.0 green:68.0/255.0 blue:142.0/255.0 alpha:1.0],
NSForegroundColorAttributeName,
nil] forState:UIControlStateNormal];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithTitle:@"OK" style:UIBarButtonItemStyleDone target:self action:@selector(setTimePicker)];
[doneBtn setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor colorWithRed:253.0/255.0 green:68.0/255.0 blue:142.0/255.0 alpha:1.0],
NSForegroundColorAttributeName,
nil] forState:UIControlStateNormal];
NSArray *itemArray = [[NSArray alloc] initWithObjects:cancelBtn, flexSpace, titleButton, flexSpace, doneBtn, nil];
[pickerToolbar setItems:itemArray animated:YES];
if(iPad){
[pickerToolbar setFrame:CGRectMake(0, 0, 320, 44)];
UIViewController* popoverContent = [[UIViewController alloc] init];
popoverContent.preferredContentSize = CGSizeMake(320, 216);
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 216)];
popoverView.backgroundColor = [UIColor whiteColor];
[popoverView addSubview:timePicker];
[popoverView addSubview:pickerToolbar];
popoverContent.view = popoverView;
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[popoverController presentPopoverFromRect:CGRectMake(0, pickerMarginHeight, 320, 216) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}else{
timeBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, SCREEN_HEIGHT-300, 320, 246)];
[timeBackgroundView setBackgroundColor:[UIColor colorWithRed:240/255.0 green:240/255.0 blue:240/255.0 alpha:1.0]];
[timeBackgroundView addSubview:pickerToolbar];
[timeBackgroundView addSubview:timePicker];
[self.view addSubview:timeBackgroundView];}
J'ai rencontré le même problème et l'ai résolu de cette façon, cela fonctionnera dans toutes les versions d'ios
Dans ios 8 Apple a changé tellement de choses que j'ai rencontré ici un problème dans mon propre projet donc, je veux juste fournir la solution en remplacement de UIActionsheet
.
dans ios 8 UIActionsheet
obsolète ainsi que ses méthodes déléguées également obsolètes. Au lieu de cela UIAlertController
avec prefferedstyleUIAlertControllerStyleActionSheet
est utilisé. vous pouvez également vérifier ce fil:
https://developer.Apple.com/library/ios/documentation/Uikit/reference/UIActionSheet_Class/index.html
Cet exemple fonctionnera à la fois dans ios 8 et dans la version précédente de celui-ci.
dans le fichier .h déclarer cette variable
@interface demoProfileForBuyer{
UIActionSheet *ac_sheet_fordate;
UIToolbar *pickerToolBar_fordate;
UIDatePicker *optionPickerDate;
UIAlertController *alertController;
}
dans un fichier .m
- (void)viewDidLoad
{
[super viewDidLoad];
pickerToolBar_fordate = [[UIToolbar alloc] initWithFrame:CGRectMake(-8, 0, 320, 44)];
pickerToolBar_fordate.barStyle = UIBarStyleBlack;
[pickerToolBar_fordate sizeToFit];
NSMutableArray *barItemsDate = [[NSMutableArray allkioc] init];
UIBarButtonItem *flexSpaceDate = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItemsDate addObject:flexSpaceDate];
UIBarButtonItem *doneBtnDate = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(pickerViewDoneBirthday)];
[barItemsDate addObject:doneBtnDate];
[pickerToolBar_fordate setItems:barItemsDate animated:YES];
optionPickerDate = [[UIDatePicker alloc] initWithFrame:CGRectMake(-8, 44, 320, 200)];
optionPickerDate.datePickerMode = UIDatePickerModeDate;
[optionPickerDate setMaximumDate: [NSDate date]];
optionPickerDate.datePickerMode = UIDatePickerModeDate;
optionPickerDate.hidden = NO;
optionPickerDate.date = [NSDate date];
optionPickerDate.backgroundColor = [UIColor whiteColor];
if(IS_IOS_8){
alertController = [UIAlertController alertControllerWithTitle:@"" message:@"" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:alertAction];
[alertController addAction:alertAction];
[alertController addAction:alertAction];
[alertController addAction:alertAction];
[alertController.view addSubview:pickerToolBar_fordate];
[alertController.view addSubview:optionPickerDate];
} else {
ac_sheet_fordate = [[UIActionSheet alloc] initWithTitle:@"test"
delegate:self
cancelButtonTitle:@"cancel"
destructiveButtonTitle:nil
otherButtonTitles:@"dev",@"dev", nil];
[ac_sheet_fordate setActionSheetStyle:UIActionSheetStyleBlackOpaque];
[ac_sheet_fordate setBackgroundColor:[UIColor blackColor]];
[ac_sheet_fordate addSubview:pickerToolBar_fordate];
[ac_sheet_fordate addSubview:optionPickerDate];
}
}
// when date picker open
- (IBAction)showBirthdayPicker:(id)sender{
// self.view.frame = CGRectMake(0, -220, self.view.frame.size.width, self.view.frame.size.height);
UIButton *btnsender = sender;
//[ac_sheet_fordate showInView:self.view];
self.scrForEditProfile.contentSize = CGSizeMake(320, 1000);
if(IS_IOS_8){
popover = alertController.popoverPresentationController;
if (popover)
{
popover.sourceView = sender;
popover.sourceRect = CGRectMake(0, btnsender.bounds.Origin.y, btnsender.bounds.size.width, btnsender.bounds.size.height);
popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
}
[self presentViewController:alertController animated:YES completion:nil];
} else {
if(IS_IOS_7){
[ac_sheet_fordate showInView:[UIApplication sharedApplication].keyWindow];
ac_sheet_fordate.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height-ac_sheet_fordate.frame.size.height, [UIScreen mainScreen].bounds.size.width, ac_sheet_fordate.frame.size.height);
}
else{
[ac_sheet_fordate showInView:self.view];
}
}
if(IS_IOS_7==FALSE && IS_HEIGHT_GTE_568==FALSE){
[self.scrForEditProfile scrollRectToVisible:CGRectMake(self.txtDOB.frame.Origin.x, self.txtDOB.frame.Origin.y + 200, self.txtDOB.frame.size.width, self.txtDOB.frame.size.height) animated:NO];
}
else{
[self.scrForEditProfile scrollRectToVisible:CGRectMake(self.txtDOB.frame.Origin.x, self.txtDOB.frame.Origin.y +300, self.txtDOB.frame.size.width, self.txtDOB.frame.size.height) animated:NO];
}
}
// when date picker open user tap on done button
- (IBAction)pickerViewDoneBirthday{
if(IS_IOS_8){
[self.presentedViewController dismissViewControllerAnimated:NO completion:nil];
} else {
[ac_sheet_fordate dismissWithClickedButtonIndex:0 animated:YES];
}
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"dd/MM/yyyy"];
birthday_date = optionPickerDate.date;
[self.btnShowDatePicker setTitle:[formatter stringFromDate:optionPickerDate.date] forState:UIControlStateNormal];
[self.btnShowDatePicker setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.btnShowDatePicker setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted];
self.scrForEditProfile.contentSize=CGSizeMake(320 , 700);
[self.scrForEditProfile scrollsToTop];
}
vous pouvez également consulter mon blog, http://ioscodesample.blogspot.in/2014/10/ios-8-changes-for-actionsheet.html
Merci.
Essayez d'utiliser cette simulation de feuille d'action:
@interface UIViewController (ActionSheetSimulation)
-(UIView*) actionSheetSimulationWithPickerView:(UIPickerView*)pickerView withToolbar: (UIToolbar*)pickerToolbar;
-(void)dismissActionSheetSimulation:(UIView*)actionSheetSimulation;
@end
#import "UIViewController+ActionSheetSimulation.h"
@implementation UIViewController (ActionSheetSimulation)
-(UIView *)actionSheetSimulationWithPickerView:(UIPickerView *)pickerView withToolbar:(UIToolbar *)pickerToolbar {
UIView* simulatedActionSheetView = [[UIView alloc] initWithFrame:CGRectMake(0,
0,
UIScreen.mainScreen.bounds.size.width,
UIScreen.mainScreen.bounds.size.height)];
[simulatedActionSheetView setBackgroundColor:[UIColor clearColor]];
CGFloat pickerViewYpositionHidden = UIScreen.mainScreen.bounds.size.height + pickerToolbar.frame.size.height;
CGFloat pickerViewYposition = UIScreen.mainScreen.bounds.size.height -
pickerView.frame.size.height +
UIApplication.sharedApplication.statusBarFrame.size.height;
[pickerView setFrame:CGRectMake(pickerView.frame.Origin.x,
pickerViewYpositionHidden,
pickerView.frame.size.width,
pickerView.frame.size.height)];
[pickerToolbar setFrame:CGRectMake(pickerToolbar.frame.Origin.x,
pickerViewYpositionHidden,
pickerToolbar.frame.size.width,
pickerToolbar.frame.size.height)];
pickerView.backgroundColor = [UIColor whiteColor];
[simulatedActionSheetView addSubview:pickerToolbar];
[simulatedActionSheetView addSubview:pickerView];
[UIApplication.sharedApplication.keyWindow?UIApplication.sharedApplication.keyWindow:UIApplication.sharedApplication.windows[0]
addSubview:simulatedActionSheetView];
[simulatedActionSheetView.superview bringSubviewToFront:simulatedActionSheetView];
[UIView animateWithDuration:0.25f
animations:^{
[simulatedActionSheetView setBackgroundColor:[[UIColor darkGrayColor] colorWithAlphaComponent:0.5]];
[self.view setTintAdjustmentMode:UIViewTintAdjustmentModeDimmed];
[self.navigationController.navigationBar setTintAdjustmentMode:UIViewTintAdjustmentModeDimmed];
[pickerView setFrame:CGRectMake(pickerView.frame.Origin.x,
pickerViewYposition,
pickerView.frame.size.width,
pickerView.frame.size.height)];
[pickerToolbar setFrame:CGRectMake(pickerToolbar.frame.Origin.x,
pickerViewYposition,
pickerToolbar.frame.size.width,
pickerToolbar.frame.size.height)];
}
completion:nil];
return simulatedActionSheetView;
}
-(void)dismissActionSheetSimulation:(UIView*)actionSheetSimulation {
[UIView animateWithDuration:0.25f
animations:^{
[actionSheetSimulation setBackgroundColor:[UIColor clearColor]];
[self.view setTintAdjustmentMode:UIViewTintAdjustmentModeNormal];
[self.navigationController.navigationBar setTintAdjustmentMode:UIViewTintAdjustmentModeNormal];
[actionSheetSimulation.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UIView* v = (UIView*)obj;
[v setFrame:CGRectMake(v.frame.Origin.x,
UIScreen.mainScreen.bounds.size.height,
v.frame.size.width,
v.frame.size.height)];
}];
}
completion:^(BOOL finished) {
[actionSheetSimulation removeFromSuperview];
}];
}
@end
J'ai le même problème avec vous, montrant qu'une UIPickerView avec UIActionSheet ne fonctionne pas dans iOS 8. Parce que UIActionSheet est déconseillé et Apple recommande d'utiliser UIAlertController. Nous devons donc arrondir au vent.
J'ai écrit du code pour résoudre mon cas. J'espère que cela peut vous aider.
#define CONTENT_HEIGHT 478
- (void)initSheetWithWidth:(CGFloat)aWidth
{
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
UIAlertController *sheet = [UIAlertController alertControllerWithTitle:@"hack space" message:@"\n\n\n\n\n\n\n\n\n\n\n" preferredStyle:UIAlertControllerStyleActionSheet];
[sheet.view setBounds:CGRectMake(7, 0, aWidth, CONTENT_HEIGHT)]; // Kinda hacky
self.sheet = sheet;
} else {
UIActionSheet *sheet = [[UIActionSheet alloc] init];
self.sheet = sheet;
}
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, aWidth, CONTENT_HEIGHT)];
[view setBackgroundColor:[UIColor whiteColor]];
UIToolbar *toolbar = [[UIToolbar alloc]
initWithFrame:CGRectMake(0, 0, aWidth, 0)];
toolbar.barStyle = UIBarStyleDefault;
[toolbar sizeToFit];
[toolbar setItems:@[
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(pickerSheetCancel)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(pickerSheetDone)]
]];
UIDatePicker *picker = [[UIDatePicker alloc]
initWithFrame:CGRectMake(0, toolbar.bounds.size.height, aWidth, 0)];
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
UIAlertController *sheet = self.sheet;
[view addSubview:toolbar];
[view addSubview:picker];
[sheet.view addSubview:view];
} else {
UIActionSheet *sheet = self.sheet;
[sheet addSubview:toolbar];
[sheet addSubview:picker];
}
self.picker = picker;
}
- (void)showWithDate:(NSDate*)date {
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
// Reload and select first item
[self.picker setDate:date];
[self.parentViewController presentViewController:self.sheet animated:YES completion:nil];
} else {
UIActionSheet *sheet = self.sheet;
[self.sheet showInView:self.containerView];
// XXX: Kinda hacky, but seems to be the only way to make it display correctly.
[self.sheet
setBounds:CGRectMake(0, 0,
self.containerView.frame.size.width,
sheet.frame.size.height - CONTENT_HEIGHT)];
// Reload and select first item
[self.picker setDate:date];
[UIView animateWithDuration:0.25 animations:^{
[self.sheet
setBounds:CGRectMake(0, 0,
self.containerView.frame.size.width,
sheet.frame.size.height)];
}];
}
}
Je pense que c'est tout pour résoudre ce problème. Bon codage!
Swift 5
Vous pouvez utiliser un UIAlertController
pour ce faire.
@IBAction func btnActionDate(_ sender: Any) {
let picker = UIPickerView(frame: CGRect(x: 0, y: 50, width: self.view.frame.size.width - 16.0, height: 150))
picker.delegate = self
picker.dataSource = self
// let message = "\n\n\n\n\n\n"
let alert = UIAlertController(title: "Title of Action Sheet", message: "", preferredStyle: UIAlertController.Style.actionSheet)
alert.isModalInPopover = true
picker.reloadAllComponents()
//Add the picker to the alert controller
alert.view.addSubview(picker)
// For setting height of Action sheet
let height:NSLayoutConstraint = NSLayoutConstraint(item: alert.view!, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 350)
alert.view.addConstraint(height)
let okAction = UIAlertAction(title: "Done", style: .default, handler: {
(alert: UIAlertAction!) -> Void in
let fetchedObj = picker.selectedRow(inComponent: 0)
})
alert.addAction(okAction)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil)
}
Définissez les délégués et la source de données du sélecteur
class MyViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource
définir les fonctions de délégué et de source de données
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return arrayMonthData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return arrayMonthData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
}
func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
return self.view.frame.size.width - 16.0
}
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
return 36.0
}
Regardez mon code
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil
message:@"\n\n\n\n\n\n\n\n\n\n\n" preferredStyle:UIAlertControllerStyleActionSheet];
__weak typeof(self) weakSelf = self;
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"确认"style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
[weakSelf pickActionSheetFinishAction];
[alertController addAction:cancelAction];
[alertController.view addSubview:self.topicPickView];
[self presentViewController:alertController animated:YES completion:nil];