runway20 / PopoverView

A simple UIView popover control for iPhone/iPad written in CoreGraphics.
1.02k stars 213 forks source link

add landscape and rotation support #17

Closed gereons closed 11 years ago

gereons commented 11 years ago

adds landscape support for PopoverView, better rotation support for the demo project.

ocrickard commented 11 years ago

Hey, Good work, but I'm seeing some weird behavior when I rotate. Any idea what's going on?

iOS Simulator Screen shot 5 Jan 2013 09 32 41

gereons commented 11 years ago

Oops. That happens when you remove portrait mode from the list of supported orientations of the app. I'll look into it.

gereons commented 11 years ago

Hm. I can't reproduce this any more, after cleaning my project. I also think that under iOS5, the list of supported orientations that you specify in Xcode / info.plist must agree with the code in - (BOOL)shouldAutorotateToInterfaceOrientation:

ocrickard commented 11 years ago

Hmm, I just pulled a fresh copy of your repo again, and still get the same behavior on both iOS 5 and 6. I don't have time to debug this right now, but I think the fix should be relatively simple. Perhaps a little project for my weekend.

I really appreciate the time you spent on trying to improve the component!

gereons commented 11 years ago

That's really weird, everything works as it should on my end. What's particularly baffling is that the "tap anywhere" label isn't centered in landscape - I can't imagine how my changes would allow for that. Are you sure you're using my landscape branch? https://github.com/gereons/PopoverView/tree/landscape

ocrickard commented 11 years ago

OK, yep, you were right. I wasn't on your landscape branch. Sorry.

Now that I have it running, when I test on device, your modification to the "topWindow" code is causing a crash with the following output:

*** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [nan nan]'

I believe that for this case, the UIWindow which is on top has no valid subviews, and the topView var has nil value, resulting in NaN when I divide by 0 on line 590. This only occurs in specific device states where the UIWindow stack is set up in a way that is different than we usually assume, but it does happen (as evidenced by the other issue that relates to this).

However, I really do like your approach to finding the top window. So, my suggested fix is to simply set topView to topWindow instead. UIWindow is a subclass of UIView, so it is valid to add subviews directly to the window. So:

topView = topWindow;

When I do this, it works beautifully on my devices.

Again, this is excellent work, and you have really improved the quality of the component. Thank you.

gereons commented 11 years ago

topView = topWindow; doesn't work for apps that do not support portrait at all. I'll look into it.

ocrickard commented 11 years ago

I just tested on an app that doesn't support portrait -- it looks OK to me. What are your concerns there?

gereons commented 11 years ago

With just topView = topWindow I still had problems with apps supporting only landscape. I've just commited and pushed what I believe is the fix for this to my branch; I've also changed some color values to use the definitions from PopoverView_Configuration.h

ocrickard commented 11 years ago

Awesome. Thanks. I'll test this today.

stefanaerts commented 11 years ago

Hi, how can i unload/remove a popoverView? I create on every new character in a textView searchField a new connection with the new searchString. the data is assigned to a new popoverView in the connection did finished.

   if (connection == self.connectionGetAllTitles) {
        self.searchResultArray = [NSMutableArray new];
        NSError *error;
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.data options:kNilOptions error:&error];
        if (!error) {
            NSArray *tempMovieArray =[dict objectForKey:@"results"];
            for (NSDictionary *movieDict in tempMovieArray) {
                Movie *movie =[Movie new];
                movie.movieID =[[movieDict objectForKey:@"id"] intValue];
                movie.title =[movieDict objectForKey:@"title"];
                movie.posterPath =[movieDict objectForKey:@"poster_path"];
            movie.releaseDate = [movieDict objectForKey:@"release_date"];

                [self.searchResultArray addObject:movie];
            }
            self.tableview = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 200, 800)];
            self.tableview.delegate = self;
            self.tableview.dataSource = self;
            CGPoint point = CGPointMake(self.view.frame.size.width - 10, 20);
            self.pv = [PopoverView showPopoverAtPoint:point
                                               inView:self.view
                                      withContentView:self.tableview
                                             delegate:self];
        }

The problem is when i goToDetail as i click on 1 row in the tableview in the popover: the popover doesnt go away, i want to unload/hide whatever it. But i cant get rid of it. I have to click on a couple of popovers that are loaded on the same CGPoint during the searchString entering.

How can i remove the existing popover before i add a new Popoverview with the code self.pv = [PopoverView showPopoverAtPoint:point inView:self.view withContentView:self.tableview delegate:self];

Thanks, kind rg Stefan.

Spokane-Dude commented 11 years ago
[self dismissViewControllerAnimated: YES completion: nil];
ocrickard commented 11 years ago

I hope Spokane-Dude's answer helped.

Here's my 2 cents:

From briefly looking at your code, and reading your description, it would appear to me that you're losing your reference to your popoverview within the view stack. Are you ever dismissing self.pv before setting a new one there? You must dismiss the control manually if it already exists on the view stack.

Another way to deal with this is to just update the table view, and only show the popover if self.pv is nil. No use in constantly creating new table views/popovers when you really just want to update the one you have.

So, in short, make sure you don't create a new popover every time this method is called, or if you do, make sure you kill the old one first.

stefanaerts commented 11 years ago

Hi guys, thanks. Bot answers i had to do. 1)in tableView didSelectRowAtIndexPath: -> [self.pv dismiss:TRUE];

2)and in connectionDidFinishLoading if (self.tableview != nil) { [self.tableview reloadData]; } else{ CGPoint point = CGPointMake(self.view.frame.size.width - 10, 20); self.tableview = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 200, 800)]; self.tableview.delegate = self; self.tableview.dataSource = self; self.pv = [PopoverView showPopoverAtPoint:point inView:self.view withContentView:self.tableview delegate:self]; }

stefanaerts commented 11 years ago

Guys, Everything works now,but only as long as i dont turn my simulator from landscape to portrait and visa versa. AS of the moment i turn my simulator the search popoverview is not shown any more. Do I have to do something to handle the orientation switch? I have my project enabled for all types orientation.Other stuff works when i turn my simulator,but the popover not. kind regards Stefan.

stefanaerts commented 11 years ago

Please ignore my last point. I found the problem, i had to put the tableview=nil every where i go to detail screen.

jjxtra commented 11 years ago

Rotation is broken in the latest code. On iPad, I present from a point, then rotate to landscape and the popover doesn't take the rotation into account, it ends up floating in the middle right of the window.