web-dev-qa-db-ja.com

iOS8でUIActionSheetを使用してUIPickerViewを表示しない

iOS8UIPickerViewUIActionSheetを表示しない

コードはiOS7で動作しますが、iOS8では動作しません。 UIActionSheetがiOS8およびApple推奨されるUIAlertController

しかし、iOS8でそれを行う方法は? UIAlertControllerを使用する必要がありますか?

iOS7
enter image description here

iOS8
enter image description here

編集:

私のGitHubプロジェクトが問題を解決しています。

33
Gabriel.Massana

UIActionSheetのリファレンスから:

UIActionSheetはサブクラス化するように設計されていません。また、階層にビューを追加する必要もありません。 UIActionSheet APIによって提供されるよりも多くのカスタマイズを使用してシートを表示する必要がある場合、独自のシートを作成し、presentViewController:animated:completion:でモーダルに表示できます。

私の推測は、あなたが正確にその理由を見ていることです。

UIAlertControllerのリファレンスには同様の免責事項はありませんが、インターフェイスを見ると、Appleはリリース前に追加されます。

私の推奨事項は、ピッカーとボタンを含む小さなビューを作成し、必要に応じて表示および非表示にすることです。それはそれほど難しくなく、意図した用途を超えてインターフェースをプッシュしません。

14
David Berry

同じ視覚効果を達成するには、ActionSheetPicker-3.を使用できます。これは iOS 8

実際、もうUIActionSheetではありません。しかし、まったく同じように見えるため、iOS 8で動作します。

animation

6
skywinder

UIActionSheetはiOS8で廃止されました。 UIAlertControllerforiOS8以降

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

参照: IAlertController

例: https://github.com/KiritVaghela/UIAlertController

4
Kirit Vaghela

IOS8ではUIActionSheetの代わりに自分でタイムピッカーを記述します。

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];}
4
folse

私は同じ問題に直面し、すべてのiOSバージョンで動作するようにこの方法で解決しました

IOS 8では、Appleは私がここで自分のプロジェクトで1つの問題に直面した多くのことを変更したので、UIActionsheetの代わりに解決策を提供したいだけです。

ios 8 UIActionsheetでは非推奨になり、デリゲートメソッドも非推奨になりました。代わりにUIAlertControllerをprefferedstyleで
UIAlertControllerStyleActionSheetが使用されます。このスレッドも確認できます:

https://developer.Apple.com/library/ios/documentation/Uikit/reference/UIActionSheet_Class/index.html

この例は、iOS 8と以前のバージョンの両方で機能します。

.hファイルでこの変数を宣言します

@interface demoProfileForBuyer{
 UIActionSheet *ac_sheet_fordate;
 UIToolbar *pickerToolBar_fordate;

 UIDatePicker *optionPickerDate;
 UIAlertController *alertController;
}

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

}

私のブログも確認できます http://ioscodesample.blogspot.in/2014/10/ios-8-changes-for-actionsheet.html

ありがとう。

2
Banker Mittal

このアクションシートシミュレーションを使用してみてください。

@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
2
Bulky_ooti

UIActionSheetが廃止され、AppleはUIAlertControllerを使用することを推奨しています。

私は私のケースを解決するためにいくつかのコードを書きました。それがあなたのお役に立てば幸いです。

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

この問題を修正するのはすべてだと思います。ハッピーコーディング!

1

Swift 5

これを行うには、UIAlertControllerを使用できます。

@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)
    }

このようにpickerViewのデリゲートとデータソースを設定します

class MyViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource

デリゲートとデータソース関数を設定します

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
    }
1
Bali

私のコードを見てください

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];
1
fish.wang