UA-17470720-3

Jump to content


Photo
- - - - -

Tab Bar Controller


  • Please log in to reply
24 replies to this topic

#1 Adam Chin

Adam Chin

    Sr. Member

  • STV 2.0
  • PipPipPip
  • 42 posts
Reputation: 5
Good

Posted 23 March 2011 - 04:44 PM

Hi,

Apologies in advance if this is covered somewhere on the forum...

Wondering if there's a way to persist a consistent tab bar controller while navigating thru UITableViewControllers? One of my apps has that typical steady state tab bar across the bottom, and while I'm retrofitting in STV (actually re-purposing the app to be STV), I noticed that my tab bars swipe away as I navigate into lower details....

Thanks in advance!
Adam

#2 Panamind

Panamind

    Experienced Member

  • STV 3.0 Pro
  • PipPipPipPip
  • 77 posts
Reputation: 1
Good

Posted 23 March 2011 - 04:59 PM

As you likely know, a UITabBarController is a UIViewController that manages other UIViewController via tabs. Your RootViewController contains the UITabBarController instead of it's view being the view of the UITabBarController.

Hope that helps

#3 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 23 March 2011 - 05:12 PM

Hi guys,

Adam: If I correctly understand what you mean, all you need is set your SCArrayOfObjectsSection/Model "detailViewHidesBottomBar" property to FALSE.

Hope this helps!

#4 Adam Chin

Adam Chin

    Sr. Member

  • STV 2.0
  • PipPipPip
  • 42 posts
Reputation: 5
Good

Posted 23 March 2011 - 05:19 PM

Yes, I believe that's what I was looking for.

Thanks guys!

#5 Adam Chin

Adam Chin

    Sr. Member

  • STV 2.0
  • PipPipPip
  • 42 posts
Reputation: 5
Good

Posted 23 March 2011 - 10:52 PM

Hi guys,

Adam: If I correctly understand what you mean, all you need is set your SCArrayOfObjectsSection/Model "detailViewHidesBottomBar" property to FALSE.

Hope this helps!


After checking into this, my use of SCObjectSection presented another little challenge.

Another question if you don't mind..

I'm prepping my object section with:

SCObjectSection *objectSection = [SCObjectSection sectionWithHeaderTitle:nil withBoundObject:eventObject
withClassDefinition:profDef];

And detailViewHidesBottomBar fits with SCArrayOfObjectsSection/Model

Any quick / obvious thoughts?

Thanks!

#6 Adam Chin

Adam Chin

    Sr. Member

  • STV 2.0
  • PipPipPip
  • 42 posts
Reputation: 5
Good

Posted 24 March 2011 - 11:00 PM

I was thinking that my prior post may have not had enough context around it, and this may help:

The purpose of using SCObjectSection, as a prep to an individual section at the top that ultimately presents itself like a preferences app... Nickname editable cell at the top..

Posted Image

Code below which leads up to SCObjectSection:



tableModel = [[SCTableViewModel alloc] initWithTableView:self.tableView withViewController:self];


// Get the Profile object (if exists, otherwise create a new one)
NSManagedObject *profObject = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:profDef.entity];
NSArray *objectsArray = [profDef.managedObjectContext executeFetchRequest:fetchRequest error:NULL];
if(objectsArray.count)
profObject = [objectsArray objectAtIndex:0];
[fetchRequest release];
if(!profObject)
{
// create a new object
profObject = [NSEntityDescription insertNewObjectForEntityForName:[profDef.entity name]
inManagedObjectContext:profDef.managedObjectContext];
}

SCObjectSection *objectSection = [SCObjectSection sectionWithHeaderTitle:nil withBoundObject:profObject
withClassDefinition:profDef];

[tableModel addSection:objectSection];

#7 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 25 March 2011 - 02:28 AM

Hi Adam,

Thanks for the update. detailViewHidesBottomBar is also a property of SCTableViewCell.

...
for(int i=0; i<objectSection.cellsCount; i++)
  [objectSection cellAtIndex:i].detailViewHidesBottomBar = FALSE;
...

Hope this helps :)

#8 Adam Chin

Adam Chin

    Sr. Member

  • STV 2.0
  • PipPipPip
  • 42 posts
Reputation: 5
Good

Posted 25 March 2011 - 10:57 AM

Thanks Tarek!

I'm thinking I'll need to do an SCTableViewCell override given as I drill down and add related objects during the 1 ViewDidLoad, the tab bar ends up going away.

I'm Testing this morning, but if you think this is a un-recommended idea let me know.

Reality is this, I'm showing my "Fresh Boarder" colors here on how best to do things with STV.
This being said, I truly appreciate your, and all the senior boarder feedback.

#9 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 25 March 2011 - 04:28 PM

Hi Adam,

Please hold back from doing anything. We're releasing an STV update in the next couple of days, and I'll make sure that STV will detect if you assign detailViewHidesBottomBar to a cell, and will automatically have all the detail cells inherit that. Hope this helps :)

#10 Adam Chin

Adam Chin

    Sr. Member

  • STV 2.0
  • PipPipPip
  • 42 posts
Reputation: 5
Good

Posted 25 March 2011 - 04:36 PM

Hey Tarek,

Thanks for the heads up. Much appreciated!

Best,
Adam

#11 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 28 March 2011 - 06:01 PM

Hi Adam,

I'm thinking I'll need to do an SCTableViewCell override given as I drill down and add related objects during the 1 ViewDidLoad, the tab bar ends up going away.


Please accept my apologies here, what I actually overlooked is that you're referring to an SCTableViewCell and not an SCTableViewSection. In an SCTableViewSection, when you set detailViewHidesBottomBar, STV should propagate that to all its cells. In the case of SCTableViewCell, it does not need to propagate anything, as the detail cells would already have their tab bar hidden.

Would you please rephrase the text I quoted above so that I would be able to get a better understanding of your problem? I apologize again for the confusion.

#12 Adam Chin

Adam Chin

    Sr. Member

  • STV 2.0
  • PipPipPip
  • 42 posts
Reputation: 5
Good

Posted 28 March 2011 - 10:08 PM

Hi Tarek,

Maybe I need to start over with the explanation. And pictures will help with visually.
I'd like my tab bar to persist at "as many levels" while drilling down, adding entities of
the table view - common HIG for the most part...

So it starts here where:

Posted Image

Then drilling down to add or edit a Favorite:

Posted Image

Then my tab bar goes away at this next level down:

Posted Image

And here's the implementation code (some old code not removed yet for date formatting):

#import "ProfileView.h"
#import "HBAppDelegate.h"


@implementation ProfileView


#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
	[super viewDidLoad];
	
	NSManagedObjectContext *managedObjectContext = [(HBAppDelegate *)[UIApplication sharedApplication].delegate managedObjectContext];
	
	
	// Create a class definition for Favorites
	SCClassDefinition *favorites =
	[SCClassDefinition definitionWithEntityName:@"Favorites" withManagedObjectContext:managedObjectContext
							  withPropertyNames:[NSArray arrayWithObjects:@"name", @"category",nil]];
	
	SCPropertyDefinition *favDef = [favorites propertyDefinitionWithName:@"category"];
	favDef.type = SCPropertyTypeSelection;
	favDef.attributes = [SCSelectionAttributes attributesWithItems:[NSArray arrayWithObjects:@"This", @"That", @"The other thing", nil]  
											allowMultipleSelection:NO
												  allowNoSelection:NO];
						 
	
	// Create a class definition for Dates
	SCClassDefinition *dates =
	[SCClassDefinition definitionWithEntityName:@"Dates" withManagedObjectContext:managedObjectContext
							  withPropertyNames:[NSArray arrayWithObjects:@"name", @"date",nil]];
	
  	dates.uiElementDelegate = self;
	
	SCPropertyDefinition *datedate = [dates propertyDefinitionWithName:@"date"];
	datedate.type = SCPropertyTypeDate;
	datedate.required = FALSE;
	datedate.title = @"Name";
	
	
	SCPropertyDefinition *dateName = [dates propertyDefinitionWithName:@"name"];
	dateName.title = @"Name";
	dateName.type = SCPropertyTypeTextField;
	
	
	SCPropertyDefinition *apptDatePropertyDef = [dates propertyDefinitionWithName:@"date"];
	apptDatePropertyDef.type = SCPropertyTypeDate;
	apptDatePropertyDef.required = TRUE;
	apptDatePropertyDef.title = @"Date";
	
	
	NSDateFormatter *apptDateFormatter = [[NSDateFormatter alloc] init];
	[apptDateFormatter setDateFormat: @"MM-dd-yyyy" ];
	apptDatePropertyDef.attributes = [SCDateAttributes attributesWithDateFormatter:apptDateFormatter];
	[apptDateFormatter release];

	
	// Create a class definition for Sizes
	SCClassDefinition *sizes =
	[SCClassDefinition definitionWithEntityName:@"Sizes" withManagedObjectContext:managedObjectContext
							  withPropertyNames:[NSArray arrayWithObjects:@"type", @"value",nil]];
	// Date field def
	SCPropertyDefinition *sizeDef = [sizes propertyDefinitionWithName:@"type"];
	sizeDef.title = @"Type";
	sizeDef.type = SCPropertyTypeTextField;
	
	
	// Create a class definition for Profile
	SCClassDefinition *profDef =
	[SCClassDefinition definitionWithEntityName:@"Profile" withManagedObjectContext:managedObjectContext
							  withPropertyNames: [NSArray arrayWithObjects:@"nickname", @"favorites", @"dates", @"sizes", nil]]; 
	
	// Profile field Def
	SCPropertyDefinition *eventPDef = [profDef propertyDefinitionWithName:@"nickname"];
	eventPDef.title = @"Nickname";
	eventPDef.type = SCPropertyTypeTextField;
	
	
	// relationships
	
	// ** favorites relationship
	SCPropertyDefinition *favPropDef = [profDef propertyDefinitionWithName:@"favorites"];
	favPropDef.attributes = [SCArrayOfObjectsAttributes attributesWithObjectClassDefinition:favorites 
																		   allowAddingItems:TRUE 
																		 allowDeletingItems:TRUE 
																		   allowMovingItems:FALSE];
	
	// ** dates relationship
	SCPropertyDefinition *datePropDef = [profDef propertyDefinitionWithName:@"dates"];
	datePropDef.attributes = [SCArrayOfObjectsAttributes attributesWithObjectClassDefinition:dates 
																			allowAddingItems:TRUE 
																		  allowDeletingItems:TRUE 
																			allowMovingItems:FALSE];
	
	// ** size relationship
	SCPropertyDefinition *sizePropDef = [profDef propertyDefinitionWithName:@"sizes"];
	sizePropDef.attributes = [SCArrayOfObjectsAttributes attributesWithObjectClassDefinition:sizes 
																			allowAddingItems:TRUE 
																		  allowDeletingItems:TRUE 
																			allowMovingItems:FALSE];

	
	tableModel = [[SCTableViewModel alloc] initWithTableView:self.tableView withViewController:self];
  
	// This is to place an Editable cell at the top for Nickname
	// Get the Profile object (if exists, otherwise create a new one)
	NSManagedObject *nickNameObject = nil;
	NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
	[fetchRequest setEntity:profDef.entity];
	NSArray *objectsArray = [profDef.managedObjectContext executeFetchRequest:fetchRequest error:NULL];
	if(objectsArray.count)
		nickNameObject = [objectsArray objectAtIndex:0];
	[fetchRequest release];
	if(!nickNameObject)
	{
		// create a new object
		nickNameObject = [NSEntityDescription insertNewObjectForEntityForName:[profDef.entity name]
													inManagedObjectContext:profDef.managedObjectContext];
	}
	
 
	SCObjectSection *objectSection = [SCObjectSection sectionWithHeaderTitle:nil withBoundObject:nickNameObject
														withClassDefinition:profDef];
	 
	// for loop put in place to keep tab bar persistent
	// this works to a point... how about once someone starts adding values to a lower hierachy?
	// perhaps I need more than ViewDidLoad, or an override
 
	// Thanks for the update. detailViewHidesBottomBar is also a property of SCTableViewCell - Tarek
	// Hold on working this thru per Tarek, he's got a fix - 3/25
   
	for(int i=0; i<objectSection.cellCount; i++) {
		[objectSection cellAtIndex:i].detailViewHidesBottomBar = FALSE;
		
	}
	
	// Probably need an SCTableViewCell override.
	
	[tableModel addSection:objectSection];
}



- (void)dealloc {
	
	[tableModel release];
	
	[super dealloc];
}


- (void)willConfigureCell:(SCTableViewCell *)cell
{
	if([cell isKindOfClass:[SCDateCell class]])
	{
		SCDateCell *dateCell = (SCDateCell *)cell;
		dateCell.datePicker.datePickerMode = UIDatePickerModeDate;
	}
}

@end



Hope this explains it better....

Thanks,
Adam

#13 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 28 March 2011 - 10:48 PM

Hi Adam,

Thanks a lot for the detailed explanation. When you need to set a property of a cell that's deep down into the detail view hierarchy, you basically have two options:

* Option 1

Set a delegate directly for this cell. This can be easily done by setting the uiElementDelegate property of the class definition that will generate the cell. Please note that a cell's delegate must conform to the SCTableViewCellDelegate protocol (what this essentially means for you is that you need to go to your view controller's header file and add SCTableViewCellDelegate to the list of protocols). Here is how you should set uiElementDelegate in your case:

...
favorites.uiElementDelegate = self; 
...

Next, you'll just implement the SCTableViewCellDelegate method called willConfigureCell, which is the best place to configure the detailViewHidesBottomBar property you want to set:

- (void)willConfigureCell:(SCTableViewCell *)cell
{
  cell.detailViewHidesBottomBar = TRUE;
}


* Option 2

While option 2 may seem a little bit more complicated, it's usually very powerful when you want to perform the same operation on all detail views.

The game plan here is to assign a tag to each of the detail models that is equivalent to their level in the heirarchy. We'll do this by implementing the SCTableViewModelDelegate method called detailModelCreatedForRowAtIndexPath, which gets called every time a detail model is created. We'll also need to assign a delegate to each detail model, otherwise the delegate methods we'll implement are not going to get called for it. Finally, we should implement SCTableViewModelDelegate's willConfigureCell method, and depending on the model's tag, we'll decide whether to show or hide the tab bar. This is all implemented in a way that's much easier than it sounds:

- (void)tableViewModel:(SCTableViewModel *)tableViewModel detailModelCreatedForRowAtIndexPath:(NSIndexPath *)indexPath detailTableViewModel:(SCTableViewModel *)detailTableViewModel
{
  // Set a tag equivalent to the detail model's level in the hierarchy
  detailTableViewModel.tag = tableViewModel.tag + 1;

  // Set the detail model's delegate
  detailTableViewModel.delegate = self;
}

- (void)tableViewModel:(SCTableViewModel *)tableViewModel willConfigureCell:(SCTableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
  // 0 is the main model, 1 is the Favorites level in your hierarchy
  if(tableViewModel.tag == 1)   
	cell.detailViewHidesBottomBar = TRUE;
}

The power behind option 2 is that, for example, I can configure all date cells in your entire application (all detail views) just by implementing the willConfigureCell method.

Hope this helps!

#14 Adam Chin

Adam Chin

    Sr. Member

  • STV 2.0
  • PipPipPip
  • 42 posts
Reputation: 5
Good

Posted 28 March 2011 - 11:02 PM

Hi Tarek,

Both make sense to me, option 2 is most appealing.
I hope this thread will help others with similar questions.

Thanks for the great level of detail, and two viable options!

I'll check it out in practice now :)

Best,
Adam

#15 Adam Chin

Adam Chin

    Sr. Member

  • STV 2.0
  • PipPipPip
  • 42 posts
Reputation: 5
Good

Posted 29 March 2011 - 03:12 AM

Hi Tarek,

I actually tried both options and I'm not seeing the expected behavior for some reason.

There's something obviously missing in my code. I've set my delegates, and the only thing possibly questionable to me is I've left in the for loop we touched on earlier in the thread.

Can I send you the project to have a quick look?

Thanks,
Adam

#16 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 30 March 2011 - 03:03 PM

Hi Adam,

Thanks for sending in your project. I see your point, setting detailViewHidesBottomBar to FALSE only affects one level of detail views. We'll fix that in an update coming in a couple of days (2.0.3). Thanks again!

#17 Adam Chin

Adam Chin

    Sr. Member

  • STV 2.0
  • PipPipPip
  • 42 posts
Reputation: 5
Good

Posted 30 March 2011 - 03:16 PM

Hi Tarek,

Thanks for the time on investigating this.

As always, I appreciate your efforts!

Best,
Adam
  • Tarek and Thomas Hempel like this

#18 Raj Devershetty

Raj Devershetty

    Sr. Member

  • STV 3.0 Pro
  • PipPipPip
  • 48 posts
Reputation: 2
Good

Posted 06 April 2011 - 09:20 AM

I've tried the below code to hide the tab bar for one of the detail view. The tab bar does'nt show at the bottom or detailview title. I'm using the latest code 2.0.3 which has fix for the detailViewHidesBottomBar to show the tab bar at the bottom of the detailView page. Anything missing?

- (void)tableViewModel:(SCTableViewModel *)tableViewModel detailModelCreatedForRowAtIndexPath:(NSIndexPath *)indexPath detailTableViewModel:(SCTableViewModel *)detailTableViewModel
{
// Set a tag equivalent to the detail model's level in the hierarchy
detailTableViewModel.tag = tableViewModel.tag + 1;

// Set the detail model's delegate
detailTableViewModel.delegate = self;
}

- (void)tableViewModel:(SCTableViewModel *) tableViewModel willConfigureCell:(SCTableViewCell *) cell forRowAtIndexPath:(NSIndexPath *) indexPath
{
cell.height = 45;
cell.editable = FALSE;
cell.movable = FALSE;
if([cell isKindOfClass:[SCTextViewCell class]])
{
SCTextViewCell *scTextViewCell = (SCTextViewCell *)cell;
scTextViewCell.maximumHeight = 1000;
}
// 0 is the main model, 1 is the Table View Detail level in your hierarchy
if(tableViewModel.tag == 1){
cell.detailViewHidesBottomBar = FALSE;
cell.detailViewTitle=@"My Detials View Title";
}

}

#19 Adam Chin

Adam Chin

    Sr. Member

  • STV 2.0
  • PipPipPip
  • 42 posts
Reputation: 5
Good

Posted 06 April 2011 - 10:03 AM

Hi Adam,

Thanks for sending in your project. I see your point, setting detailViewHidesBottomBar to FALSE only affects one level of detail views. We'll fix that in an update coming in a couple of days (2.0.3). Thanks again!


Tarek,

Thanks so much for the fix! And the release of 2.0.3:

http://www.sensiblecocoa.com/forum/announcements/2392-minor-update-stv-203.html

I tested it and it works beautifully!

Cheers!
Adam

#20 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 06 April 2011 - 04:43 PM

Hi Raj,

Your tab bar is hidden since you're setting it to FALSE on the second level. Try changing "if(tableViewModel.tag == 1)" to "if(tableViewModel.tag == 0)". Also, if you're creating an SCArrayOfObjectsSection in your model, then you should set its detailViewHidesBottomBar property to FALSE.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users