Popover size to be the same as content?


#1

During the solving of the bronze solution I was trying to make the asset list popover window the same size as its content and couldn’t achieve it.
I tried everything and was unable to set the height of the popover to the content it has, it always goes right to the bottom. The only other thing I could do is to set it fixed with setPopoverContentSize, but then it wouldn’t work if the content goes beyond this size.
For me it looks like this even with your solution:

I would be very happy if something could explain me how to do it, cause it’s eating me for a few days already.
Is it really possible to set the height of the popover to the content size or to set it to some fixed size but be able to stretch if content grows?
Thanks.


#2

Why not just dynamically grow the popoverContentSize based on the number of elements in allAssetTypes? If each cell is about 44 pixels and you want a little buffer, you could implement something like:

        CGSize popWindow;
        popWindow.width = 320;
        popWindow.height = 44 * ([[[BNRItemStore sharedStore] allAssetTypes] count] +2);
        [assetPickerPopover setPopoverContentSize:popWindow];

#3

Tried this, didn’t work… maybe I’m doing this wrong? Now it is even worse - the popover goes from up top till the very bottom.
Since the only way to present popover in our case is presentPopoverFromRect:inView:permittedArrowDirections:animated: method this is what I did

		
	CGSize popWindow; // your code here
        popWindow.width = 320;
        popWindow.height = 44 * ([[[BNRItemStore sharedStore] allAssetTypes] count] +2);
        [assetPickerPopover setPopoverContentSize:popWindow];

	CGPoint buttonCenter = [assetTypeButton center]; // to make a rect for the method below starting from the center of the asset button
	CGRect rect = CGRectMake(buttonCenter.x, buttonCenter.y, popWindow.width, popWindow.height);
		
        assetPickerPopover = [[UIPopoverController alloc] initWithContentViewController:atp];
        [assetPickerPopover setDelegate:self];

        [assetPickerPopover presentPopoverFromRect:rect
						         	   inView:[self view]
			              permittedArrowDirections:UIPopoverArrowDirectionAny
					 		       animated:YES];

#4

I’ll take a quick look through your code. When I implemented my code it ended up looking like:


#5

My code is similar except I take a short cut for the rect portion. I’m going to supply my full code for this section in the event the problem is somewhere else in this section:

- (IBAction)showAssetTypePicker:(id)sender
{
    if ([assetPickerPopover isPopoverVisible]) {
        // If the popover is already up, get rid of it
        [assetPickerPopover dismissPopoverAnimated:YES];
        assetPickerPopover = nil;
        return;
    }
    
    [[self view] endEditing:YES];
    
    AssetTypePicker *assetTypePicker = [[AssetTypePicker alloc] init];
    [assetTypePicker setItem:item];
    
    // Place image picker on the screen
    // Check for iPad device before instantiating the popover controller
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        // Create a new popover controller that will display the imagePicker
        assetPickerPopover = [[UIPopoverController alloc] initWithContentViewController:assetTypePicker];
        
        CGSize popWindow;
        popWindow.width = 320;
        popWindow.height = 44 * ([[[BNRItemStore sharedStore] allAssetTypes] count] +2);
        [assetPickerPopover setPopoverContentSize:popWindow];
        
        [assetPickerPopover setDelegate:self];
        
        // For Bronze Challenge in AssetTypePicker
        [assetTypePicker setDvc:self];
        [assetTypePicker setPopoverController:assetPickerPopover];
        
        // Display the popover controller
        [assetPickerPopover presentPopoverFromRect:[sender frame] inView:[self view] permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
        
    } else {
        [[self navigationController] pushViewController:assetTypePicker animated:YES];
        
    }
    
}

Can you send a screen shot / the rest of your code in that section?


#6

Oh, what the hell?!.. maybe there is some piece of code that interrupts the popover size settings for this?..
Maybe you could post your code for both sides to see if I have something that messes things up?
I do this from - (IBAction)showAssetTypePicker:(id)sender method in DetailViewController


#7

Yes here is mine code for this method:

- (IBAction)showAssetTypePicker:(id)sender
{
	[[self view] endEditing:YES];
	
	AssetTypePicker *atp = [[AssetTypePicker alloc] init];
    [atp setItem:item];
	
	if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {

	CGSize popWindow;
        popWindow.width = 320;
        popWindow.height = 44 * ([[[BNRItemStore sharedStore] allAssetTypes] count] +2);
        [assetPickerPopover setPopoverContentSize:popWindow];
		CGPoint buttonCenter = [assetTypeButton center];
		
		CGRect rect = CGRectMake(buttonCenter.x, buttonCenter.y, popWindow.width, popWindow.height);
		
        assetPickerPopover = [[UIPopoverController alloc] initWithContentViewController:atp];
        [assetPickerPopover setDelegate:self];

        [assetPickerPopover presentPopoverFromRect:rect
										    inView:[self view]
						  permittedArrowDirections:UIPopoverArrowDirectionAny
										  animated:YES];
		[atp setPopoverController: assetPickerPopover];
		[atp setController:self];
		

    } else {
//        [self presentViewController:imagePicker animated:YES completion:nil];
		[[self navigationController] pushViewController:atp
											   animated:YES];
    }
	
}

#8

Okay, I got this… my mistake was that I put

assetPickerPopover = [[UIPopoverController alloc] initWithContentViewController:atp];

line after setPopoverContentSize. So it wasn’t set… stupid me.
Thanks man, really helped me!


#9

One question to you though, what’s [assetTypePicker setDvc:self]; doing in your code?


#10

I’m passing a pointer of the DetailViewController to AssetTypePicker. That way I can I can update the txt in assetTypeButton with a method I added called: (void)updateAssetTypeButton. That way my clean up section in AssetTypePicker looks like:

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        
        [popoverController dismissPopoverAnimated:YES];
         popoverController = nil;
        [dvc updateAssetTypeButton];
        
        
    }

#11

Oh I see, I should have guess myself considering it’s called dvc. Yeah I did the same in mine code, just called it controller.
Anyway, thanks again!


#12

During the updating the code for the silver challenge encountered this problem again: I have the “add new asset” button on the navbar of AssetTypePicker view, so when you click it you go to the next slide/view to add an asset. But when you switch back the popover size gets back to the default no matter what I do.
I tried to set the AssetTypePicker popover size in viewDidLoad, viewWillAppear etc, nothing helps… in some cases it tries to go to the right size but then resizes itself right away.
Any ideas maybe?
It looks like this:


#13

if you either want to post all your code or provide a link so I can download the proj file, I’m happy to take a look at it.


#14

Sure, here you go
dl.dropbox.com/u/8620623/Homepwnerchapter16.zip


#15

I see what you’re saying. If I change the width of popWindow.width I can see that viewWillAppear is executing the code, but as you’ve pointed out, something then is resetting all the parameters of the window.

After digging for a while to see what might be resetting the window, I came up empty handed. So instead I found a solution which solves from the problem and gets you where you want to be. I did come across something that feels like a bug in xcode, but it was the only way to make it work.

Here were the steps to make it work:

  1. turn popWindow in a @property CGSize popWindow in AssetTypePicker.h
  2. @synthesize
  3. in ViewWillAppear
  • remove CGSize
  • update popWindow.width = 321;
  1. in the numberOfRowsInSection function add:
  • [thisPopover setPopoverContentSize:popWindow];

And things don’t work! The weird thing is that if you leave popWindow.width = 320 it doesn’t work. I to goes to full height. But by adding one pixel it works properly.

Weird but solved! Joe might be able to explain why the popoverWindow gets reset when returning from the +

Hope this helps!


#16

Wow, yeah, it is weird… don’t get it. Though now it works, thanks!
Yes, maybe Joe will be able to explain this situation…