i want to make popup like this
http://dl.dropbox.com/u/1898217/la-foto.jpg
Means... In Backend My Ipad Form has Primary Detail Of Books
IN UITableView,,
When I Select Row Then DetailPage Which Is PopUp Like Above Link,,
How I Can .. ?
I AM TRYing This Code
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Here UIPopoverController Is Use
self.popOverControl = [[UIPopoverController alloc]initWithNibName:"DetailPage" bundle:nil];
self.popOverControl.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self.view addSubview:self.popOverControl.view]; // view is the transparent background
[self.popOverControl viewWillAppear:YES];
}
Looking to the image you provided, It does not seem to be UIPopoverController. It is just UIViewController added in the center of the screen by setting appropriate height, width and x,y position.
[self.view addSubView:yourPopOverController.view]
Related
I have a UITableViewController with many cells, each cell contains four text fields vertical on each other, a pop over is presented by tapping on any text field, however, this pop over contains a text field when tapped the keyboard is fired and most likely the pop over will be shifted up to prevent the keyboard from hiding its text field (this is the default behavior of the pop over), but in the background (the dimmed view), the tableViewController loses its correct scrolling behavior to keep the pop over presenting-textField on the track while the keyboard is visible ..
a sample project can be downloaded here.
how can I offset the table view to keep the pop over presenting-textField on screen while keyboard is visible in this case ?
I tried the well-known TPKeyboardAvoiding library but it didn't solve the issue.
p.s. tableViewController works well for the first 3 or 4 keyboard firings, but loses precise scrolling on later attempts.
Screenshot (the green text field is the text field which presented the pop over, but tableViewController scrolls to the incorrect text field indicated in red):
any help would be highly appreciated.
EDIT:
this question is not a duplicate for: Making a UITableView scroll when text field is selected
because the text field that I need the table view to scroll to is the one that fires a pop over not a keyboard, and scrollToRowAtIndexPath does not work precisely in this case because each cell contains 4 text fields.
use (CGRect)convertRect:(CGRect)rect toView:(UIView *)view to get cell position on tableviews superview and accordingly handle the tableview offset
Here is my solution :
Change into
TableViewController.m
1. Register for keyboard Notifications (UIKeyboardWillShowNotification, UIKeyboardWillHideNotification)
2. Create local variables:
CGSize _currentPopoverContentSize; //if you want to have custom size for popover
UIView *_currentPopoverSender; //to remember from wich view you will present popover
BOOL _keyboardIsShown; //enable in keyboardWillShow, and disable in keyboardWillHide
3. In my presentPopover method:
- (void)presentPopoverControllerWithSize:(CGSize)size fromView:(UIView *)sender{
MyController *controller = [[[MyController alloc] init] autorelease];
if (self.popover)
{
[_popover release];
_popover = nil;
}
_popover = [[UIPopoverController alloc] initWithContentViewController:controller];
_popover.popoverContentSize = size;
_popover.delegate = self;
//checking if keyboard is shown - if NO, than present popover, if YES - just `resignFirstResponder` for your _`activeTextField`(you can set it in -textFieldDidBeginEditing: and nullify in -textFieldDidEndEditing:)
if (!_keyboardIsShown)
{
[_popover presentPopoverFromRect:[sender bounds]
inView:sender
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
_popOver.popoverContentSize = CGSizeMake(320, 700);
}
else
{
[_activeTextField resignFirstResponder];
}
_currentPopoverContentSize = size;
_currentPopoverSender = sender;
}
4. Than:
- (void)keyboardWillBeHidden:(NSNotification*)aNotification{
[UIView animateWithDuration:0.3
animations:^{
//do some stuff
_popOver.popoverContentSize = CGSizeMake(320, 700);
} completion:^(BOOL finished) {
if (_popover && _currentPopoverSender)
{
[_popover presentPopoverFromRect:[_currentPopoverSender bounds]
inView:_currentPopoverSender
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
}
}];
_keyboardIsShown = NO;
}
5.:
-(void)textFieldDidBeginEditing:(UITextField *)textField{
[textField resignFirstResponder];
[self presentPopoverControllerWithSize:textField.frame.size fromView:_activeText];
// self.vc = [[self storyboard] instantiateViewControllerWithIdentifier:#"ProductSourcePopOver"];
//
// if(_popOver == nil){ //make sure popover isn't displayed more than once in the view
// _popOver = [[UIPopoverController alloc]initWithContentViewController:self.vc];
// }
// _popOver.popoverContentSize = CGSizeMake(320, 700);
//
// [_popOver presentPopoverFromRect:_activeText.frame inView:_activeText permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
// _popOver.delegate = self;
}
This might helps you :)
Change the entire view frame size.
For example, keyboard height is 100 then,
CGRect frame = self.view.frame;
self.view.frame = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height - keyboardHeight);
Then call didSelectRowAtIndexPath method again for the same indexPath, so it will reload the popover.
This is just a base idea, there might be some modifications required to achieve exact behavior.
Hope this will help you.
How about add the tag(00 01 02 03, 10 11 12 13...etc) for each UITextfield in the cell, From tens digit you can know which cell, from single digits you know which textfield.
Register for UIKeyboardWillShowNotification and when that selector gets triggered, call your pop over code:
[self presentPopoverControllerWithSize:textField.frame.size fromView:_activeText];
The reason for this is that the iOS handles itself presenting the popover and handling it's frame. So it's generally a good practice to present the pop over after the keyboard is shown.
Hope this helps..
What I am trying to do is display a smaller view on top of a UITableView when a UITableViewCell is clicked. I don't want to transition to another UIViewController but "popup" a view on top of the UITableView that will house more information about the UITableViewCell clicked.
I don't think I am looking for a UIAlertView, but I am looking for a UIView that I can put labels, buttons, pictures, etc. on.
I hope my terminology is correct. I am still a newb :)
Leon
p.s. All my searching just came up with UIAlertView stuff.
Try using didSelectRowAtIndexPath delegate function of the UITableView, the code is untested to give you an idea:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Assuming view is at zero index of XIB file.
// this view will contain all lable and other controls
UIView *customView = (UIView *)[[NSBundle mainBundle] loadNibNamed:#"NameOfCustomViewXIBFile" owner:nil options:nil] objectAtIndex:0];
customView.transform = CGAffineTransformMakeScale(0.0f, 0.0f);
[self.view addSubView:customView];
[UIView animateWithDuration:0.5
animations:
^{
customView.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
}
];
}
Hope it helps!
EDIT:
Animation to remove this popup:
customView.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
[UIView animateWithDuration:0.5
animations:
^{
customView.transform = CGAffineTransformMakeScale(0.0f, 0.0f);
}
];
[customView removeFromSuperView];
The problem with the existing answer is that if the user scrolls the table so that the cell goes offscreen and back on, the view that you popped up is likely to be gone due to cell re-use. To avoid this, you must store something in the cell's "model" so that every time cellForRowAtIndexPath: is called, you re-generate the cell with its popup view if it is supposed to be there. Just displaying from didSelectRowAtIndexPath: may be insufficient.
The approach I'd prefer for this if I were coding it is to make all the cells your own subclass of UITableViewCell. This subclass includes an extra BOOL showPopup. In your setter setShowPopup: you set the value, and also create & show or destroy/remove/hide the "popup" subview for that cell. (You could make the subview a class member that's always around, allocate and assign it when needed, and keep a reference, just showing/hiding as needed; that's a size/space performance trade-off.)
-(void) setShowPopup:(BOOL show) {
showPopup = show;
if(show) {
// create subview, and add to view
} else {
// remove and destroy subview
}
}
And in UITableView delegate/datasource:
-(UITableViewCell) UITableView:(UITableView *table) cellForRowAtIndexPath:(NSIndexPath *ip) {
// usual stuff to get a reusable cell or allocate a new one, and prepare it for display
// then
if(showPopup) {
// create subview and add to view
} else {
// remove and destroy subview
}
}
I used a UIButton for something similar in a GLKViewController so this might work for a UITableViewController. I just disabled the button and added a rounded border so it looked like a custom popup. When the user clicked on something interesting, I changed the hidden flag on the button to show or hide it.
Something like this to make it look pop-up-y
In viewDidLoad:
// make info "popup"
_infoBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_infoBtn.bounds = CGRectMake( 0, 0, kRightButtonBarDim, kRightButtonBarDim);
_infoBtn.backgroundColor = [UIColor colorWithWhite:1 alpha:0.75];
_infoBtn.selected = NO;
_infoBtn.titleLabel.font = [UIFont boldSystemFontOfSize:kTableCellFontSize];
_infoBtn.titleLabel.lineBreakMode = NSLineBreakByCharWrapping;
[_infoBtn setTitleColor:[UIColor colorWithWhite:.3 alpha:1] forState:UIControlStateDisabled];
// border
_infoBtn.layer.cornerRadius = 5; // rounded corners
// drop shadow
_infoBtn.layer.masksToBounds = NO;
_infoBtn.layer.shadowColor = [UIColor blackColor].CGColor;
_infoBtn.layer.shadowOpacity = 0.8;
_infoBtn.layer.shadowRadius = 12;
_infoBtn.layer.shadowOffset = CGSizeMake(12.0f, 12.0f);
_infoBtn.enabled = NO;
_infoBtn.hidden = YES;
[self.view addSubview:_infoBtn];
Then in tableView's didSelectRowAtIndexPath update any information needed in the button and set hidden to NO. You should be able to add any necessary subviews to this UIButton.
_infoBtn.frame = CGRectMake(20, 20, 20, 20); // set this wherever you like
[_infoBtn setTitle:#"text" forState:UIControlStateDisabled];
_infoBtn.hidden = NO;
I just tested this for a UIViewController that has a UITableView as a subview and it looked the same. Scrolling did not affect it (i.e., the button did not move with scrolling, almost like a HUD) because the button was added to the top-level UIView. Dunno if this is what you need, but hopefully it will give you some ideas.
I have a UIViewController inside of UINavigationViewController. I use navigationController.toolbar for some actions.
There's no problem until the first device rotation. After it toolbar goes off the screen frame.
And there's nothing to be done, even another device rotations can't fix this.
The problem occurs only on IPad ios v.6.
The code is very simple:
- (void)createToolbar{
UIImage *toolbarBack = [[UIImage imageNamed:#"navbar"] resizableImageWithCapInsets:UIEdgeInsetsMake(2, 2, 2, 2)];
[self.navigationController.toolbar setBackgroundImage:toolbarBack forToolbarPosition:UIBarPositionBottom barMetrics:UIBarMetricsDefault];
self.navigationController.toolbar.delegate = self;
//...
self.toolbarItems = #[item1, space, item2, space, item3, space, item4];
}
- (void)showToolbar{
[self.navigationController setToolbarHidden:YES animated:NO];
}
#pragma mark - toolbar delegate methods
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar{
return UIBarPositionBottom;
}
UPDATE
I found out that before the rotation navigationController.view.height == 1004 and after the rotations it increase by 20 (1024). Is it some statusbar issue?
Set up toolbar delegate to your view controller and implement method:
- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar {
return UIBarPositionBottom;
}
If you use storyboard you can create constraint between bottom of the screen and your toolbar.
I have a popover that displays from a UITableViewCell in a UITableView, which is the only view in a modal dialog. This works fine in both landscape and portrait:
UIViewController *content = [[SetTimeClockTimeViewController alloc] init];
popover = [[UIPopoverController alloc] initWithContentViewController:content];
[popover setDelegate:self];
UITableViewCell *cell = [dataTable cellForRowAtIndexPath:[dataTable indexPathForSelectedRow]];
[popover presentPopoverFromRect:cell.frame inView:cell.superview permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
However, when the screen is rotated while the popover remains up, the popover shifts away from the cell (if I rotate back it shifts to the proper location). This happens if either orientation is the starting orientation. I tried implementing popoverController:willRepositionPopoverToRect:inView:, but nothing I've put in it appears to have fixed the problem. For example:
- (void)popoverController:(UIPopoverController *)popoverController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView *__autoreleasing *)view {
// TODO: Popover moves wrong when rotating
UITableViewCell *cell = [dataTable cellForRowAtIndexPath:[dataTable indexPathForSelectedRow]];
*rect = cell.frame;
*view = cell.superview;
}
I've tried telling the table to reloadData when rotating, using convertRect:toView to have self.view as the view, and calling presentPopoverFromRect:inView:permittedArrowDirections:animated in didRotateFromInterfaceOrientation:, but none of those seemed to fix the improper placement.
How can I ensure the popover is displayed from the new cell location after rotation?
Example of the popover displaying in portrait (arrow points to "Time" row):
After orientation to landscape (arrow should point to "Time" row):
Popovers displayed from a view do not maintain a relationship with the view, and might more often than not shift to incorrect places after rotation. This is unlike displaying from a bar button item, where the popover will move after layout. You should move the popover to the correct location in viewDidLayoutSubviews of the view controller.
Make sure to convert the returned rectangle to the view's correct coordinate system by using convertRect:toView: or convertRect:fromView:.
You should translate the rect to the superview using convertRect:toView. The most important part is to call it in willAnimateToInterfaceOrientation method.
The best solution I have seen for this is to use the cell(or in my case a UIButton) as the sourceView and the cell's bounds as the sourceRect.
i.e.
[popover
presentPopoverFromRect:cell.bounds //vs cell.frame
inView:cell //vs cell.superView
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
I have a UITableView with a bunch of rows. When a user taps on a row, a custom pop-up (which is a custom UIView) will appear on top of the table:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
PopUp *myPopUp = [[PopUp alloc] initWithFrame:CGRectMake(0, 0, 320, 568)];
[self.view addSubview:myPopUp];
}
I'm loading my custom UIView PopUp from a nib:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self loadNib];
}
return self;
}
- (void) loadNib
{
NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:#"PopUp" owner:self options:nil];
UIView *mainView = [subviewArray objectAtIndex:0];
[self addSubview:mainView];
}
In the PopUp, there is a button when pressed that causes the PopUp to close:
- (IBAction)closePopUp:(id)sender
{
[self removeFromSuperview];
}
The PopUp disappears when the button is pressed. However, the UITableView underneath cannot be interacted with anymore (i.e. the user cannot scroll the table, cannot tap on another row, etc.). I would like the PopUp to disappear and have the table be fully interactive again. Can anyone explain why this is happening and how I may fix this? Thanks!
Edited with screenshots
UITableView with a row of data: http://imgur.com/PlIufHI,xGKxUul,qkt27oZ#0
When a row is selected, myPopUp appears on top: http://imgur.com/PlIufHI,xGKxUul,qkt27oZ#1
When the "x" custom button is pressed, it calls closePopUp, which removes myPopUp from the superview: http://imgur.com/PlIufHI,xGKxUul,qkt27oZ#2
User is unable to interact with the table now. User cannot select a row, scroll through the table, etc.
You are actually removing the view that you loaded from the nib file, but the parent is another blank UIView that is capturing every touch within the (0, 0, 320, 568) rect.
Try removing the superview from the closePopUp method:
[self.superview removeFromSuperview];
I don't know what's going on in your specific case, but I can tell you that adding subviews to a UITableView may lead to unexpected behavior like this and it's generally a bad idea.
In order to fix what's happening and get a cleaner structure, I would suggest you to add the popup view to the window, rather than to the table view.
[self.view.window addSubview:myPopUp];