Stuck with UIActionSheetPicker , iOS

2019-08-07 09:43发布

问题:

This is going to be a very targeted question , as its for people that have actually used the UIActionSheetPicker before.

I used it in my iphone applications and everything worked great , but now that i tried to implement it on my ipad i experienced some problems.

The main problem is that on ipad the picker appears as a "bubble" or "info window" if you prefer , which points at the spot where it was called , like a button a text field etc.

Below is an example of it :

You can see that the "info window" is pointing at the animals button.

In my application i have 4 different buttons. 2 are in the top side of the screen and 2 at the bottom.

Those who are at the bottom , call the picker very well and the picker appears on top of the buttons pointing down on them.

However , the ones on the top of the screen (almost like the one in the image) when they call the picker the picker appears much lower on the screen and doesnt point at them as it should ...

I mean i expected to appear just under the buttons pointing at them (like in the image), but they are almost in the center of the screen pointing nowhere..

Any ideas? Has someone experienced this before?

EDIT


In the beginning , i was calling the ActionSheetPicker inside the buttons action like this:

- (IBAction)selectTopic:(UIControl *)sender {
[ActionSheetStringPicker showPickerWithTitle:NSLocalizedString(@"CHOOSE_TOPIC", nil) rows:self.topics initialSelection:self.selectedIndex target:self successAction:@selector(topicWasSelected:element:) cancelAction:@selector(actionPickerCancelled:) origin:sender];


//when user picks a new topic we clean the titleField to make sure selected title of previous topic doesnt mix up with new topic
        titleField.text = @"";

}

Now i am trying to call it like this:

- (IBAction)selectTopic:(UIControl *)sender {
    ActionSheetStringPicker *thePicker = [[ActionSheetStringPicker alloc] initWithTitle:NSLocalizedString(@"CHOOSE_TOPIC", nil) rows:self.topics initialSelection:self.selectedIndex target:self successAction:@selector(topicWasSelected:element:) cancelAction:@selector(actionPickerCancelled:) origin:sender];

    thePicker.presentFromRect = topicField.frame;

    [thePicker showActionSheetPicker];

    //when user picks a new topic we clean the titleField to make sure selected title of previous topic doesnt mix up with new topic
titleField.text = @"";
}

Where topicField is my TextField.

Sadly the result is the same. Even now that i am specifying where i want the arrow to point , the picker is called 300 pixels down.

The strange thing is though that even with another other button that is a bit lower than the previous the picker is again exactly 300 pixels down.

EDIT2


After noticing that the picker shows 300 pixels down , i decided to manually make it show 300pixels up , to point exactly on my button.

I used the following code :

- (IBAction)selectTopic:(UIControl *)sender {
    //[ActionSheetStringPicker showPickerWithTitle:NSLocalizedString(@"CHOOSE_TOPIC", nil) rows:self.topics initialSelection:self.selectedIndex target:self successAction:@selector(topicWasSelected:element:) cancelAction:@selector(actionPickerCancelled:) origin:sender];

    ActionSheetStringPicker *thePicker = [[ActionSheetStringPicker alloc] initWithTitle:NSLocalizedString(@"CHOOSE_TOPIC", nil) rows:self.topics initialSelection:self.selectedIndex target:self successAction:@selector(topicWasSelected:element:) cancelAction:@selector(actionPickerCancelled:) origin:sender];


    CGRect pickerFrame = topicField.frame;
    pickerFrame.size.height -= 300;
    thePicker.presentFromRect = pickerFrame;

    [thePicker showActionSheetPicker];

    //when user picks a new topic we clean the titleField to make sure selected title of previous topic doesnt mix up with new topic
    titleField.text = @"";

}

Amazingly the button once again appears in the same position 300pixels down. I start to believe that this one may not be the property to alter the position of the picker.

Any ideas ?

回答1:

Setting the presentFromRect in your calling code won't make a difference since it will be reset based on the sender within the ActionSheetPicker code, instead you are going to need to modify the source code of the library.

The following (unmerged) commit on github should resolve the issue On iPad, set the popover to point properly at its container.

Basically within the AbstractActionSheetPicker.m file modify the - (void)presentPickerForView:(UIView *)aView method like the following

- (void)presentPickerForView:(UIView *)aView {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
     self.presentFromRect = CGRectMake(0, 0, self.containerView.frame.size.width, self.containerView.frame.size.height);
        [self configureAndPresentPopoverForView:aView];
    }
    else {
         self.presentFromRect = aView.frame;
        [self configureAndPresentActionSheetForView:aView];
    }
}


回答2:

After a brief look at the code, I would say that you want to make sure that the presentFromRect on the ActionPicker object is in the coordinates of the container that you are passing in on the init. For instance if I had one big view that contained a button:

This is untested:

UIView* someBigView = ... // get the big view
UIButton* someButton = ... // get the button that the big view contains

ActionSheetDatePicker* thePicker = [[ActionSheetDatePicker alloc] initWithTitle:@"Some Title" 
    datePickerMode:UIDatePickerModeDate 
    selectedDate:[NSDate date] 
    target:self 
    action:@selector(someMethod:) 
    origin:someBigView];

//the arrow should be pointing at the button
thePicker.presentFromRect = someButton.frame;

[thePicker showActionSheetPicker];

In my opinion, this library has a pretty big flaw in the fact that it takes an origin parameter that can be a button item or a container. It requires that you look at the source to understand it, instead of being (somewhat) obvious from the interface.