Is there any way to present an UIPopover from an UITableView index? - ipad

I would like to present an UIPopover from an UITableView specific index.
Here's my code:
if (indexPath.row == 5) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
EnginesPopoverController *enginesPopoverController = [[EnginesPopoverController alloc] initWithNibName:#"EnginesPopoverController" bundle:nil];
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:enginesPopoverController];
self.popoverController = popover;
popoverController.delegate = self;
[popover release];
[enginesPopoverController release];
CGPoint point = {670, 600};
CGSize size = {450, 216};
[popoverController presentPopoverFromRect:CGRectMake(point.x, point.y, size.width, size.height) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
If I try to present the Popover from an UIButton it goes well...
Thanks!

This is what I do:
CGRect cellRect = [self.tableView rectForRowAtIndexPath:indexPath];
CGRect popoverRect = CGRectMake(self.view.bounds.size.width - self.popoverController.popoverContentSize.width,
CGRectGetMidY(cellRect),
1.0, 1.0);
The x location I use places the popover on the right-hand side of the screen. This may not be what you want. To find the actual touch point, you can use gesture recognizers.
In return, please try to answer my related question: Popover's arrow to track an object in a scrollview

Manipulating David's code I arrived at this:
(my pop is called "storytPop")- my popover is from the toolbar and I wanted the next tableview to show to the right.
CGRect cellRect = [self.tableView rectForRowAtIndexPath:indexPath];
[self.storytPop presentPopoverFromRect:cellRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];

Related

UICollectionView full screen zoom on UICollectionViewCell

How can you zoom in on a UICollectionViewCell so that it will be displayed full screen? I have extended UICollectionViewFlowLayout and in my view controller when a cell is tapped I'm doing this:
CGPoint pointInCollectionView = [gesture locationInView:self.collectionView];
NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:pointInCollectionView];
UICollectionViewCell *selectedCell = [self.collectionView cellForItemAtIndexPath:selectedIndexPath];
NSLog(#"Selected cell %#", selectedIndexPath);
Not really sure where to go from here. Should the UICollectionView be responsible of showing the zoomed in cell? Or should I create a new view controller that displays the content of the cell (an image) in full screen?
I took the solution here and modified it slightly to work with a collection view instead. I also added a transparent gray background to hide the original view a bit (assuming the image doesn't take up the entire frame).
#implementation CollectionViewController
{
UIImageView *fullScreenImageView;
UIImageView *originalImageView;
}
...
// in whatever method you're using to detect the cell selection
CGPoint pointInCollectionView = [gesture locationInView:self.collectionView];
NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:pointInCollectionView];
UICollectionViewCell *selectedCell = [self.collectionView cellForItemAtIndexPath:selectedIndexPath];
originalImageView = [selectedCell imageView]; // or whatever cell element holds your image that you want to zoom
fullScreenImageView = [[UIImageView alloc] init];
[fullScreenImageView setContentMode:UIViewContentModeScaleAspectFit];
fullScreenImageView.image = [originalImageView image];
// ***********************************************************************************
// You can either use this to zoom in from the center of your cell
CGRect tempPoint = CGRectMake(originalImageView.center.x, originalImageView.center.y, 0, 0);
// OR, if you want to zoom from the tapped point...
CGRect tempPoint = CGRectMake(pointInCollectionView.x, pointInCollectionView.y, 0, 0);
// ***********************************************************************************
CGRect startingPoint = [self.view convertRect:tempPoint fromView:[self.collectionView cellForItemAtIndexPath:selectedIndexPath]];
[fullScreenImageView setFrame:startingPoint];
[fullScreenImageView setBackgroundColor:[[UIColor lightGrayColor] colorWithAlphaComponent:0.9f]];
[self.view addSubview:fullScreenImageView];
[UIView animateWithDuration:0.4
animations:^{
[fullScreenImageView setFrame:CGRectMake(0,
0,
self.view.bounds.size.width,
self.view.bounds.size.height)];
}];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(fullScreenImageViewTapped:)];
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
[fullScreenImageView addGestureRecognizer:singleTap];
[fullScreenImageView setUserInteractionEnabled:YES];
...
- (void)fullScreenImageViewTapped:(UIGestureRecognizer *)gestureRecognizer {
CGRect point=[self.view convertRect:originalImageView.bounds fromView:originalImageView];
gestureRecognizer.view.backgroundColor=[UIColor clearColor];
[UIView animateWithDuration:0.5
animations:^{
[(UIImageView *)gestureRecognizer.view setFrame:point];
}];
[self performSelector:#selector(animationDone:) withObject:[gestureRecognizer view] afterDelay:0.4];
}
-(void)animationDone:(UIView *)view
{
[fullScreenImageView removeFromSuperview];
fullScreenImageView = nil;
}
You can simply use another layout (similar to the one you already have) wherein the item size is larger, and then do setCollectionViewLayout:animated:completion: on the collectionView.
You don't need a new view controller. Your datasource remains the same. You can even use the same cell Class, just make sure that it knows when to layout things for a larger cell content size, and when not to.
I'm quite sure that's how Facebook does it in Paper, as there is no reloading of the content, i.e. [collectionView reloadData] never seems to be called (would have caused flickering and resetting of the scroll offset, etc). This seems to be the most straight forward possible solution.
CGPoint pointInCollectionView = [gesture locationInView:self.collectionView];
NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:pointInCollectionView];
UICollectionViewCell *selectedCell = [self.collectionView cellForItemAtIndexPath:selectedIndexPath];
NSLog(#"Selected cell %#", selectedIndexPath);
__weak typeof(self) weakSelf = self;
[self.collectionView setCollectionViewLayout:newLayout animated:YES completion:^{
[weakSelf.collectionView scrollToItemAtIndexPath:selectedIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
}];
You can use MWPhotoBrowser, which is suitable for your problem. It supports Grid with Tap to Zoom functionality. you can get it from here
Grid
In order to properly show the grid of thumbnails, you must ensure the property enableGrid is set to YES, and implement the following delegate method:
(id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser thumbPhotoAtIndex:(NSUInteger)index;
The photo browser can also start on the grid by enabling the startOnGrid property.

How the prevent the popover from hiding with status bar in iOS6

I have a popover, which is presented from the code:
CGPoint screenPoint = [self.mapView screenPoint: self.selectedObject.pointCoordinate];
CGRect rect = CGRectMake(screenPoint.x, screenPoint.y, 1, 1);
[self.detailViewPopover presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
As u can see on the screenshot - the popover is hiding by the status bar - is it possible the exclude the status bar frame from the area where popover should be displayed?
The content size for view in popover looks like this:
self.contentSizeForViewInPopover = CGSizeMake (320, self.view.frame.size.height - 100);
You reset the UIPopoverArrowDirectionUp to UIPopoverArrowDirectionAny
[self.listViewPopover presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

nib objects aren't changing at runtime

Hello i have a nib file which contains 3 UIButtons , i need to change the attributes of button at runtime after loading from nib but i don't know what am i doing wrong. I have also NSlog after changing the booleans but i always get '0' in output. Any help thx
-(void)SettingBtnPressed:(id)sender
{
UIButton *btn =(UIButton*)sender;
UITableViewCell *btncell =(UITableViewCell *)[btn superview];
if ([[recentActivities objectAtIndex:btn.tag] isKindOfClass:[MeetingSummary class]]) {
[MainManager getSharedInstance].Summary = [recentActivities objectAtIndex:btn.tag];
MeetingSummary *ms=[recentActivities objectAtIndex:btn.tag];
Meeting *m=ms.meeting;
if(![popoverController isPopoverVisible]){
lastPoint = sender;
if (![m.endedDate isEqualToString:#"1/1/0001"]) {
if (settingpop) {
[settingpop release];
}
settingpop = [[SettingsPopViewController alloc] initWithNibName:#"SettingsPopViewController" bundle:nil];
settingpop.start.hidden=YES;
settingpop.start.enabled=NO;
NSLog(#"%i",settingpop.start.hidden);
NSLog(#"%i",settingpop.start.enabled);
settingpop.btnShowDetail.enabled=NO;
settingpop.btnShowDetail.hidden=YES;
// [settingpop.start removeFromSuperview];
// [settingpop.btnShowDetail removeFromSuperview];
settingpop.view.frame=CGRectMake(0, 0, 250, 54);
}
else
{
settingpop = [[SettingsPopViewController alloc] initWithNibName:#"SettingsPopViewController" bundle:nil];
}
settingpop.delegate = self;
[settingpop setActivityView:self.view];
popoverController = [[[UIPopoverController alloc] initWithContentViewController:settingpop] retain];
[popoverController setPopoverContentSize:CGSizeMake(250.0f, 162.0f)];
[popoverController presentPopoverFromRect:btn.frame inView:btncell
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}else{
[popoverController dismissPopoverAnimated:YES];
}
}
}
Move the row:
settingpop.view.frame=CGRectMake(0, 0, 250, 54);
before the row:
settingpop.start.hidden=YES;
Are you talking about adjusting the properties of the start and btnShowDetail controls of SettingsPopViewController? You cannot access its controls immediately after the initWithNibName. You have to wait until after the view has been created, i.e., wait until after viewDidLoad is called, because the NIB may well not have been loaded until then.

UITabBarController with a UIPopOverController

I got a requirement where I need to implement a UIPopOverController from a UITabBarController, that is in the UITabBarController when I click one of the tabs which is called for example "pop", then the popover should show up with two fields. My question is that what is the best way to achieve this. In case if there is any example either video or just some explained material then you can also share the links with me. Just bear with me since I am getting my feet wet in the ios environment.
Any suggestions would be appreciated!
Thanks
Maks
I put together a sample project that will display a UIPopoverController above the selected UITabBarItem.
http://mobileoverlord.com/displaying-a-uipopovercontroller-from-a-uitabbaritem/
This contains a little hackery because you need to iterate through the subviews of the TabBar. Also, it may be different on iOS 5 because the background view of the TabBar is in the TabBar's subview array. Its implemented in the tabBarController delegate method
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
NSInteger index = [[self tabBarController] selectedIndex];
CGRect buttonFrame = [[[[[self tabBarController] tabBar] subviews] objectAtIndex:index+1] frame];
PopOverViewController *popoverView = [PopOverViewController new];
popoverView.contentSizeForViewInPopover = CGSizeMake(250, 300);
popover = [[UIPopoverController alloc]initWithContentViewController:popoverView];
NSLog(#"X:%f Y:%f",buttonFrame.origin.x,buttonFrame.origin.y);
[popover presentPopoverFromRect:buttonFrame inView:self.tabBarController.tabBar permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}
Here is the sample code. Feel free to comment and manipulate.
https://github.com/mobileoverlord/UITabBarPopOver-Demo
If you want to restrict it to only when a certain button is pressed you can filter the class of the incoming viewController like this
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[SecondViewController class]]) {
NSInteger index = [[self tabBarController] selectedIndex];
CGRect buttonFrame = [[[[[self tabBarController] tabBar] subviews] objectAtIndex:index+1] frame];
PopOverViewController *popoverView = [PopOverViewController new];
popoverView.contentSizeForViewInPopover = CGSizeMake(250, 300);
popover = [[UIPopoverController alloc]initWithContentViewController:popoverView];
NSLog(#"X:%f Y:%f",buttonFrame.origin.x,buttonFrame.origin.y);
[popover presentPopoverFromRect:buttonFrame inView:self.tabBarController.tabBar permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}
}
This is my solution , I was in , "https://github.com/mobileoverlord/UITabBarPopOver-Demo " on the basis of the above modifications , the following is a my Demo. https://github.com/mrhyh/iPad/tree/master/

Trouble with controlling a ScrollView from a Popover

I'm a junior and I have been really struggling to get this to work, would really appreciate some help.
I am trying to build an App where you can scroll through different WebViews by selecting an item from a table in a popover (while the popover remains in place). Unfortunately, I can't get my scrollView to move when I select an item from the popover view.
I have set up a UIScrollView with page control in a main UIViewController. The scrollView is populated with (pageViewController) UIWebViews. The main UIViewController has a nav bar with a button, when the button is clicked it creates a Popover View. When I select an item from the table in the popover view I want my UIScrollView to scroll to a certain position (equates to a selected page), but the scrollView does not move.
The method below takes the value selected from the popover and uses the page number to determine where the scrollView should scroll to, but it doesn't work because at this point my scrollView is Null.
I can supply more code if needed.
main UIViewController.m code:
- (void)setDetailItem:(id)newDetailItem {
if (detailItem != newDetailItem) {
[detailItem release];
detailItem = [newDetailItem retain];
NSString *pgnum = [[NSString alloc] initWithString:[detailItem description]];
int pg;
if(pgnum == #"Page 1"){
pg =1;
}
if(pgnum == #"Page 2"){
pg =2;
}
if(pgnum == #"Page 3"){
pg =3;
}
[pgnum release];
pageControl.currentPage = pg;
[self loadScrollViewWithPage:pg - 1];
[self loadScrollViewWithPage:pg];
[self loadScrollViewWithPage:pg + 1];
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * pg;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
pageControlUsed = YES;
}
if (popoverController != nil) {
[popoverController dismissPopoverAnimated:YES];
}
}
This is how I triggered the popOverController
The infoButton is on the navbar.
The scrollView is NOT NULL in the infoButton
- (void)infoButton:(id)sender {
NSLog(#"Entering: infoButton");
// [self inspectView:self.view level:#""];
if (self.popoverController == nil) {
PopoverViewController *popoverViewController =
[[PopoverViewController alloc]
initWithNibName:#"PopoverViewController"
bundle:[NSBundle mainBundle]];
popoverViewController.navigationItem.title = #"Navigation";
UINavigationController *navController =
[[UINavigationController alloc]
initWithRootViewController:popoverViewController];
UIPopoverController *popover =
[[UIPopoverController alloc]
initWithContentViewController:navController];
popover.delegate = self;
[popoverViewController release];
[navController release];
self.popoverController = popover;
[popover release];
//NSLog(#"User pressed the info button");
}
[self.popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; }
UIPopover, being neither the most obvious class to use memory-management wise, nor the most stable, does not require you to release it before you present it. In fact, doing so causes it to throw a fatal exception! Popovers should be released after they are removed from the screen, and/or in -dealloc.

Resources