I have a master-detail application with news. It works. In detail controller i used UIWebView.
I created comments-class with xib and am trying to add it to my detail view.
Comments are UITableViewController.
After that i can see only comments, not detail-text.
I tried to scroll my webview and there is no text. But in detailviewController i did NSLog for my text and saw it. If i set newsTextHeight to 480 i see an empty view.
What am I doing wrong?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat newsTextHeight = 250;
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
CommentsViewController *commentController = [[CommentsViewController alloc] init];
NewsItem *newsItem = [news objectAtIndex:indexPath.row];
detailViewController.description = newsItem.description;
detailViewController.title = newsItem.date;
commentController.news_id = newsItem.news_id;
detailViewController.news_id = [newsItem.news_id intValue];
int views = [newsItem.viewsCnt intValue];
views++;
NSString *strFromInt = [NSString stringWithFormat:#"%d",views];
newsItem.viewsCnt = strFromInt;
[self.tableView reloadData];
//[self.navigationController presentedViewController];
[self.navigationController pushViewController:detailViewController animated:YES];
detailViewController.navigationController.toolbarHidden = NO;
[detailViewController addChildViewController:commentController];
[commentController didMoveToParentViewController:detailViewController];
[detailViewController.view addSubview:commentController.view];
detailViewController.view.frame = CGRectMake(0, 0, detailViewController.view.bounds.size.width, newsTextHeight);
commentController.tableView.contentInset = UIEdgeInsetsMake(detailViewController.view.frame.size.height, 0, 0, 0);
[commentController release];
[detailViewController release];
}
results: http://s18.postimg.org/5cv8ftbbd/detail.png
What Kiattisak is getting at is that the problem can be that your view detailViewController.view.frame is using autolayout. And therefor won't be able to be resized programmatically. (This is if you are not using storyboards)
In InterfaceBuilder, highlight your view:
And untick the Use Autolayout box in the first tab of the attributes inspector.
Hope it helps.
Related
Using SDK 6.1, Xcode 4.6.1, I make a new project Master-Detail iOS App, ARC, no storyboards.
Then in the DetailViewController, in the viewDidLoad I add two UITableViews contained in UIViewControllers and make sure the second one is hidden like this:
- (void)viewDidLoad
{
[super viewDidLoad];
UIViewController *lViewController1 = [[UIViewController alloc] init];
UITableView *lTableView1 = [[UITableView alloc] initWithFrame: self.view.frame];
lTableView1.scrollsToTop = YES;
[lViewController1.view addSubview: lTableView1];
lTableView1.dataSource = self;
[self.view addSubview: lViewController1.view];
[self addChildViewController: lViewController1];
UIViewController *lViewController2 = [[UIViewController alloc] init];
UITableView *lTableView2 = [[UITableView alloc] initWithFrame: self.view.frame];
lTableView2.scrollsToTop = YES;
[lViewController2.view addSubview: lTableView2];
lTableView2.dataSource = self;
[self.view addSubview: lViewController2.view];
[self addChildViewController: lViewController2];
// now hide the view in view controller 2
lViewController2.view.hidden = YES;
}
(I make sure the DetailViewController is a datasource that returns 100 rows of UITableViewCells with the textLabel.text set to #"hello")
The presence of the second view controller makes that scrollsToTop (tapping on the status bar) does not work anymore. If I do not use UIViewController containment and just add two UITableViews and set the second one to be hidden, scrollsToTop does work.
What am I doing wrong?
scrollsToTop only works on a single visible view. From the documentation:
This gesture works on a single visible scroll view; if there are multiple scroll views (for example, a date picker) with this property set, or if the delegate returns NO in scrollViewShouldScrollToTop:, UIScrollView ignores the request. After the scroll view scrolls to the top of the content view, it sends the delegate a scrollViewDidScrollToTop: message.
You could try calling [tableView setContentOffset:CGPointZero animated:YES] on each of your table (or scroll) views manually instead. To do this, implement the scrollViewShouldScrollToTop: method in the UIScrollViewDelegate protocol:
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView {
[lTableView1 setContentOffset:CGPointZero animated:YES];
[lTableView2 setContentOffset:CGPointZero animated:YES];
return NO;
}
You can only set 1 ScrollView per ViewController with property .scrollsToTop = YES.
If you set 2 scrollview.scrollsTopTop = YES, it will simply stop functioning.
ie: your sample project (DetailViewController.m) update following lines,
line48: lTableView1.scrollsToTop = YES;
line56: lTableView2.scrollsToTop = NO;
then, scrollsToTop works correctly. If there are more than 1 scrollview you wish to concurrently setScrollsToTop, keep digging around. good luck!
I am currently experimenting with your project. When
lViewController2.view.hidden = YES;
is replaced with
lTableView2.hidden = YES;
then the scrolling works, even with controller containment.
I tried to insert a view between the controller's view and the table and then hide this view, but the table was not scrolling.
I tried to hide the controller by experimenting with shouldAutomaticallyForwardAppearanceMethods but the table was not scrolling.
Result: From my experiments, only one scroll view must be visible in the view hierarchy and the hidden property of the parent views is not checked out. hidden must be set to NO on all other scroll views, not their parent views.
After testing several options and various hits and try I finally settled to one final solution, i.e. setBounds: of scrollView (that is tableView in your case) and it works good. You'll have to put extra effort for animation although.
CGRect frame = scrollView.frame;
frame.origin.x = 0;
frame.origin.y = 0;
[scrollView setBounds:frame];
By the way in your case, try returning YES to
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView;
Although if not defined, assumes YES.
I have used this and now it works fine.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIViewController *lViewController1 = [[UIViewController alloc] init];
UITableView *lTableView1 = [[UITableView alloc] initWithFrame: self.view.frame];
lTableView1.scrollsToTop = YES;
[lViewController1.view addSubview: lTableView1];
lTableView1.dataSource = self;
[self.view addSubview: lViewController1.view];
[self addChildViewController: lViewController1];
lTableView1.tag=1;
UIViewController *lViewController2 = [[UIViewController alloc] init];
UITableView *lTableView2 = [[UITableView alloc] initWithFrame: self.view.frame];
lTableView2.scrollsToTop = NO;
[lViewController2.view addSubview: lTableView2];
lTableView2.dataSource = self;
[self.view addSubview: lViewController2.view];
[self addChildViewController: lViewController2];
lTableView2.tag=2;
// now hide the view in view controller 2
lViewController2.view.hidden = YES;
}
- (NSUInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSUInteger)section {
return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * const kCellIdentifier = #"MyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"hello %d %d",indexPath.row, tableView.tag];
return cell;
}
I have a tableview with responding detialview. In the detailview I have some images and labes that is loaded from a URL. I'm trying to add a UIActivityindicatorview to the cell to show that is loading. I have handled that but it shows up to late and does not disappear when I go back to the tableview. I have looked all over to find a simple solution, but failed...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ReaDetailViewController *reaDetail = [[ReaDetailViewController alloc] initWithNibName:#"ReaDetailViewController" bundle:nil];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIActivityIndicatorView *activityView =
[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[activityView startAnimating];
[cell setAccessoryView:activityView];
[activityView release];
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
{
reaDetail.petImageString = [[NSString alloc] initWithString:[[exclusiveArray objectAtIndex:indexPath.row] objectForKey:#"image"]];
reaDetail.petLabelString = [[NSString alloc] initWithString:[[exclusiveArray objectAtIndex:indexPath.row] objectForKey:#"description"]];
reaDetail.petLabelString1 = [[NSString alloc] initWithString:[[exclusiveArray objectAtIndex:indexPath.row] objectForKey:#"description1"]];
reaDetail.petLabelString2 = [[NSString alloc] initWithString:[[exclusiveArray objectAtIndex:indexPath.row] objectForKey:#"description2"]];
reaDetail.title = [[exclusiveArray objectAtIndex:indexPath.row] objectForKey:#"name"];
}
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:reaDetail animated:YES];
[reaDetail release];
}
Any help is very helpful !
I understand that you want to make the activity view to be animated while you load your view controller. The problem is the activity view won't start animating until you return from this selection method... which is about the time when your controller is ready to be pushed.
2 options then:
You could exit from the method asap, calling perfomSelector:onMainThread to do the init steps of the view controller to be pushed
Or even better, push the view controller asap, and do its init process in the viewDidLoad or viewWillAppear methods of this controller (you can add the activity controller in this new view).
If you pick the 1st option, you should call the deselectRowAtIndexPath method after you've pushed the new view controller and call stopAnimating on the indicator view from this deselectRowAtIndexPath method.
I have spent several hours on this, and tried various things. I can confirm that the didSelectRowAtIndexPath is indeed being run, and the specific object I am looking for is being returned.
The bit that isn't doing anything is the part where I am trying to display the SensDetailViewClass view. It runs the code, but the viewDidLoad method in SensDetailViewClass.m doesn't run, and the view doesn't change.
I would like to have the SensDetailViewClass displayed. I can confirm that the .xib file's owner is the SensDetailsViewClass.
Please help. Here's the code.
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// get the selected item
Sens *info = [_sensInfos objectAtIndex:indexPath.row];
// initialise the detail view controller and display it
SensDetailViewClass *details = [[SensDetailViewClass alloc] initWithNibName:#"MainWindow" bundle:nil];
// set the title of the page
[details setTitle:info.heading];
details.selectedSens = info;
[self.navigationController pushViewController:details animated:YES];
[details release];
}
UPDATE: I got it to work by using this mechanism:
[self presentModalViewController:details animated:YES];
SensDetailViewClass *details = [[SensDetailViewClass alloc] initWithNibName:#"SensDetailViewClass" bundle:nil];
[self.navigationController pushViewController:details animated:YES];
i think you are fresher so nedd to check the link of tutorial
http://www.icodeblog.com/2008/08/03/iphone-programming-tutorial-transitioning-between-views/
Are you sure your SensDetailViewClass class has MainWindow as its .xib file?
Please check it and replace nib name `
initWithNibName:#"MainWindow"
in above code
Thanks,
1 ) Are you sure y*ou have the navigation comptroller in the app* or its just the View Based application.
IF this is ok then ,
2)
// initialise the detail view controller and display it
SensDetailViewClass *details = [[SensDetailViewClass alloc] initWithNibName:#"You-Xib name for this View" bundle:nil];
// set the title of the page
[details setTitle:info.heading];
details.selectedSens = info;
[self.navigationController pushViewController:details animated:YES];
[details release];
In my project , On clicking the button the string present in the button Action method should store in popover table view cell.
I cam able to store a single sting , to the first cell ....
And now my problem is i had Four buttons each button action consists of 4 strings , and now the should at a time to the popover table view ,,,
#import "SecondDetailViewController.h"
-(IBAction)viewButtonPressed:(id)sender
{
[super viewDidUnload];
//create the view controller from nib
self.tablePopoverController = [[[TablePopoverController alloc]
initWithNibName:#"TablePopover"
bundle:[NSBundle mainBundle]] autorelease];
////-------------------------------
myArray = [[NSMutableArray alloc] initinitWithObjects:myString,myString2,myString3,myString4,myString5,myString6,nil];
tablePopoverController.getingOrder = myArray ;
NSLog(#"table popo %#",myArray);
tablePopoverController.contentSizeForViewInPopover = CGSizeMake(250, 250);
//create a popover controller
self.popoverController = [[[UIPopoverController alloc]
initWithContentViewController:tablePopoverController] autorelease];
//present the popover view non-modal with a
//refrence to the button pressed within the current view
[popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
-(IBAction)orderButtonPressed
{
myString = staterlable1.text;
[myArray addObject:myString];
NSLog(#"myArray%#",myString);
}
-(IBAction)orderButton2Pressed
{
myString2 = staterlable2.text;
NSLog(#"myArray%#",myString2);
[myArray addObject:myString2];
}
-(IBAction)orderButton3Pressed
{
myString3 = staterlable3.text;
[myArray addObject:myString3];
NSLog(#"myArray%#",myString3);
}
-(IBAction)orderButton4Pressed
{
myString4 = staterlable4.text;
[myArray addObject:myString4];
NSLog(#"myArray%#",myString4);
}
-(IBAction)orderButton5Pressed
{
myString5 = staterlable5.text;
[myArray addObject:myString5];
NSLog(#"myArray%#",myString5);
}
-(IBAction)orderButton6Pressed
{
myString6 = staterlable6.text;
[myArray addObject:myString6];
NSLog(#"myArray%#",myString6);
my Problem Is after clicking these buttons the myString1 - to - myString6 NSString objects Should Store into NSMutableArray so That i will display all the strings in the TableViewPopOverController which will popover when clicking the another button in the second detailViewController........
thanks in Advance......
The usual way to do this is to embed TablePopoverController in a UINavigationController. Then, in TablePopoverController when handling tableView:tableView didSelectRowAtIndexPath:indexPath push detailViewController into the UINavigationController.
For example, you could build Controller structure the following way (based on your example):
//create a popover controller
self.popoverController = [[[UIPopoverController alloc] initWithContentViewController:[[[UINavigationController alloc] initWithRootViewController:initWithContentViewController:tablePopoverController] autorelease]] autorelease];
It is similar to your popover-creation code, put inserts a UINavigationController under the popover. Now, in TablePopoverController you should handle row selections the usual way with a UINavigationController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
DetaiViewController *detail = [[DetaiViewController alloc] init];
/* Configure detail using indexpath here indexPath
...
*/
[self.navigationController pushViewController:detail animated:YES];
}
This will work as expected (by pushing the new view into the UINavigationController) because we set controller structure with a UINavigationController.
So I am trying to simple traverse to the next level of a table view by doing this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 1) {
FiltersController *aFiltersCont = [[FiltersController alloc] init];
aFiltersCont.displayedFilters = [appDelegate.groupedBusiness allKeys];
aFiltersCont.currentLevel = self.currentLevel + 1;
[self.navigationController pushViewController:self animated:YES];
}
}
is there any reason why this would not be pushing the controller? I had a similar problem before, but solved it by displaying the view modally. However, this time, this is in a popover and needs to slide to the next screen inside that popover. Any Ideas? Thanks in advance.
OK I am going to put some more source up here to try and help...
Inside the main view controller I have this code to make the popover from a button:
// Create and configure the filters controller.
FiltersController *aFiltersController = [[FiltersController alloc] initWithStyle:UITableViewStylePlain];
self.filtersController = aFiltersController;
filtersController.appDelegate = self.appDelegate;
UINavigationController *filtersNavController = [[UINavigationController alloc] initWithRootViewController:filtersController];
UIPopoverController *filtersPopover = [[UIPopoverController alloc] initWithContentViewController:filtersNavController];
self.filtersPopoverController = filtersPopover;
filtersPopoverController.delegate = self;
and then I have the code I first posted in my filtersController class. Does that help at all?
[self.navigationController pushViewController:self animated:YES];
Should be
[self.navigationController pushViewController:aFiltersCont animated:YES];
If you are just displaying your sublcass of UITableViewController inside a UIPopoverController, the UINavigationController will not be created for you automatically. You may need to modify the code where you are creating the UIPopoverController with something like this:
MyTableViewController *table = [[[MYTableViewController alloc] init] autorelease];
UINavigationController *nav = [[[UINavigationController alloc] initWithRootViewController:table] autorelease];
myPopover = [[UIPopoverController alloc] initWithContentViewController:nav];
Then you should be able to push and pop navigation controllers on the stack no problem.
you are pushing self which is a reference to the current view controller. you should change the line with the push to the following if aFiltersCont is the viewController you are trying to drill to.
[self.navigationController pushViewController:aFiltersCont animated:YES];
You might be confused about the index. The first index is 0 not 1, so maybe you want indexPath.row == 0?
Also, you should release aFiltersCont before returning (you're leaking a FiltersController and anything it owns every time you run this method.
So maybe this?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
FiltersController *aFiltersCont = [[[FiltersController alloc] init] autorelease];
aFiltersCont.displayedFilters = [appDelegate.groupedBusiness allKeys];
aFiltersCont.currentLevel = self.currentLevel + 1;
[self.navigationController pushViewController:aFiltersCont animated:YES];
}
}