UITableView row -- Deselecting and changing highlight:NO by selecting another row - ios

I'm just learning all this stuff, so excuse me if I'm making a glaring error.
I have an array of levels of expertise: #[#"NOVICE", #"INTERMEDIATE", #"PRO", #"ALL LEVELS"];.
The user can select up to two, but if ALL LEVELS is selected, the segue is performed and the setting saved.
What I'm trying to avoid is a user selecting NOVICE and PRO. If NOVICE is selected, I want PRO to be deselected and unhighlighted. And vice versa.
Here's what I have, but I get the error:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *organizeLevelOfPlay = self.organizeDifficultyArray[indexPath.row];
if ([organizeLevelOfPlay isEqualToString:#"ALL LEVELS"]){
[self performSegueWithIdentifier:#"MinimumNumberOfPlayers" sender:self];
} else if ([organizeLevelOfPlay isEqualToString:#"NOVICE"]){
[self.organizeDifficultyArray[2] setHighlighted:NO animated:YES]; //I get an error here.
[self.selectionArray removeObject:self.organizeDifficultyArray[2]];
[self.selectionArray addObject:organizeLevelOfPlay];
self.result = [[self.selectionArray valueForKey:#"description"] componentsJoinedByString:#"/"];
NSLog(#"%#", self.selectionArray);
} else if ([organizeLevelOfPlay isEqualToString:#"INTERMEDIATE"]) {
[self.selectionArray addObject:organizeLevelOfPlay];
self.result = [[self.selectionArray valueForKey:#"description"] componentsJoinedByString:#"/"];
NSLog(#"%#", self.selectionArray);
} else if ([organizeLevelOfPlay isEqualToString:#"PRO"]){
[self.organizeDifficultyArray[0] setHighlighted:NO animated:YES]; //I get an error here.
[self.selectionArray removeObject:self.organizeDifficultyArray[0]];
[self.selectionArray addObject:organizeLevelOfPlay];
self.result = [[self.selectionArray valueForKey:#"description"] componentsJoinedByString:#"/"];
NSLog(#"%#", self.selectionArray);
}}

try to use
-[tableView: deselectRowAtIndexPath:] function to replace the -[setHighlighted:NO animated:YES] one. #"NOVICE" and #"PRO" may be is indexpath{0,1} , indexpath{0,2}.

Related

tableview indexing confusion

I am creating simple reveal menu in my demo application. Right now what I am doing is I have a one MutableArray named MutableMenu
NSArray menu = [#"menu1",#"Menu2","Menu3",#"Menu4"];
MutableMenu = [NSMutableArray alloc]initwithArray:menu];
I am just displaying this mutable array in my by default tableview cell.
In cellForRowAtIndexPath method I am using static indexing like below code snippet
if(indexPath.row == 0){
[self performSegueWithIdentifier:SEGUE_TO_MANAGE_TASK sender:nil];
}
if(indexPath.row == 1){
[self performSegueWithIdentifier:SEGUE_TO_MANAGE_LEAVE sender:nil];
}
All is working great till now. Now I have a array that I want to check permission to display in tableview cell. For example first user have only 2 permissions from 4 menus. This user only able to access menu1 and menu2. Likewise different users different permissions.
This is my code to maintaining this scenario in viewDidLoad. All is working fine
BOOL permisson = NO;
NSArray *Roles = [USERDEFAULT objectForKey:PREF_ROLE_ARRAY];
for (NSString *temp in Roles) {
if ([temp isEqualToString:#"55"] || [temp isEqualToString:#"45"] || [temp isEqualToString:#"67"] ) {
permisson = YES;
if ([Mutablemenu containsObject:#"Team management"])
NSLog(#"Already Have");
else [Mutablemenu insertObject:#"Team management" atIndex:2];
}
}
if (!permisson) {
[Mutablemenu removeObject:#"Team management"];
[Mutablemenu insertObject:#"" atIndex:2];
[MutableImages removeObject:#"team.png"];
}
[_tableview reloadData];
All is working fine But when user have only 3 permission.My indexing is changed in didSelectRowatIndexPath. For Example first user have 4 permission then index is 0,1,2,3 but when user have 3 permission then index is 0,1,2.
But my question is how do I handle this situation in didSelectRowatIndexPath. Because every time indexing is changed.
As told by #RJV Kumar, you should have check actual menu clicked instead of indexPath in didSelectRowatIndexPath as:
if([menuArray[indexPath.row] isEqualToString: #"Menu1"]){
[self performSegueWithIdentifier:SEGUE_TO_HANDLE_MENU_1 sender:nil];
}
else if([menuArray[indexPath.row] isEqualToString: #"Menu2"]){
[self performSegueWithIdentifier:SEGUE_TO_HANDLE_MENU_2 sender:nil];
}
.
.
so on...
As per my understanding, you are finding the menu based on index, but you should not do like that,
instead of that maintain menuid or menuname to identify which menu the user selected. By this way, you don't have to worry about the index.
In didselectRow method, by comparing menuid or menuname, do your operation

In iOS - Production and staging server included in single build

I have an application having two servers STAGING and PRODUCTION. I used to release two builds with changing the servers in coding part. But now my client asked to provide a single build where we can provide an option in app settings or phone settings to chnage the URL.
I reserached a lot in stack overflow and came to know that at runtime when we select debug/release mode at the time of giving build, it can be possible but anyways it is also come under process of giving two builds.
I want to have a single build where the user can change the option of Staging/Producetion. Please help me. Is it possible. ?
You can just add a switch somewhere in your application to turn on staging mode (switch off = production). The state of this switch is saved in NSUserDefaults. Then, depending to this state, you choose the right URL of server in your code.
You can do this way -
1.In the sign in page depending upon the field you are using to enter the staging or production url ,open an UIAction sheet when the field(In my case i am using tableview cell, you can use a text field or a button) is clicked then show fields like below -
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if(indexPath.row == 2) {
[self showActionSheet];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
}
calling the action sheet above in the didselectrow which will open an action sheet as below
- (void)showActionSheet
{
NSString *actionSheetTitle = #"Choose Connection";
NSString *other1 = #"development";
NSString *other2 = #"staging";
NSString *other3 = #"production";
NSString *cancelTitle = #"Cancel";
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:actionSheetTitle
delegate:self
cancelButtonTitle:cancelTitle
destructiveButtonTitle:nil
otherButtonTitles:other1, other2, other3, nil];
[actionSheet showInView:self.view];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
//Get the name of the current pressed button
NSString *buttonTitle = [actionSheet buttonTitleAtIndex:buttonIndex];
if ([buttonTitle isEqualToString:#"development"]) {
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:nil forKey:#"UserId"];
NSLog(#"Destructive pressed --> Delete Something");
}
if ([buttonTitle isEqualToString:#"staging"]) {
NSLog(#"Other 1 pressed");
}
if ([buttonTitle isEqualToString:#"production"]) {
NSLog(#"Other 2 pressed");
}
}
and finally saving the user state like above using NSUserDefaults like above in the clicked button index.

Value stored "Bool" is never read while analyze app

How can i fix this kind of problems
here is some code
BOOL missed = NO;
if (elem.lastCall.lastMissedEvent) {
if ([elem.status intValue] == 3 && [elem.timeStamp compare:elem.lastCall.lastMissedEvent] != NSOrderedAscending) {
missed = YES;
}
}
SCBubbleViewOut *bubble = nil;
if ([cell.bubbleView isKindOfClass:[SCBubbleViewOut class]]) {
bubble = (SCBubbleViewOut *) cell.bubbleView;
}
or here is some more code snipet
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *userid = [members objectAtIndex:indexPath.row];
BOOL itsMe = NO;
if ([userid isEqualToString:[SCUserProfile currentUser].userid]) {
itsMe = YES;
[self performSegueWithIdentifier:#"SCUserProfileControllerSegue" sender:self];
}
else
{
[self showFriendDetailForUserid:userid];
}
}
from these cases i get
Value stored to "BOOL" is never read;
BOOL = itsMe , missed and bubble.
Any help is highly appreciated
Thanks in Advance.
Well, you are storing some value into a variable "missed", and you are never using the value stored. So the compiler is wondering why you are doing this, because it is pointless, and the compiler assumes that maybe you wanted to do something else.
If you stored the variable for example so that you can view it in the debugger, add a line
(void) missed;
That tells the compiler "yes, I know I store a value and I'm not using it, leave me alone". On the other hand, if that's not the case then you need to figure out what you actually wanted to do. The compiler doesn't know, and we don't know. The compiler just says "this doesn't look right", and I can only agree with it.

How can I alternate view controller and not lose data

I have two UIViewControllers, one is a UIPickerViewController, the Other a UITableViewController. Ideally the Picker should get a request from the user to add x amount of some item to the tableView. The Picker gets user inputs and assigns them to variables val1, val2, val3, where val1 is the number of items (number of rows) and val2 is the name or label for the item.
PickerViewController.m
- (IBAction)add:(id)sender
{
TableViewController *tvc = [[TableViewController alloc] init];
[tvc setValues:self.val1 :self.val2 :self.val3];
[self presentViewController:tvc animated:YES completion:nil];
}
TableViewController.m
-(void)setValues:(NSString *)newVal1 :(NSString *)newVal2 :(NSString *)newVal3
{
self.val1 = newVal1;
self.val2 = newVal2;
self.val3 = newVal3;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"UITableViewCell"];
// This is just a header which holds my "Add" button
UIView *header = self.headerView;
[self.tableView setTableHeaderView:header];
[self addNew:self.val1 :self.val2 :self.val3];
}
- (void)addNew:(NSString *)newVal1 :(NSString *)newVal2 :(NSString *)newVal3
{
if(!self.numberOfRows){
NSLog(#"Initially no of rows = %d", self.numberOfRows);
self.numberOfRows = [self.val1 intValue];
NSLog(#"Then no of rows = %d", self.numberOfRows);
}
else
{
self.numberOfRows = self.numberOfRows + [newVal1 intValue];
NSLog(#"New no rows = %d", self.numberOfRows);
}
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.numberOfRows inSection:0];
// Only run when called again .. not initially
if(self.run != 0){
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:#[indexPath]withRowAnimation:UITableViewRowAnimationBottom];
self.run ++;
[self.tableView endUpdates];
}
}
// "ADD" button which should go back to the picker and get new items to add to the table
- (IBAction)testAdd:(id)sender
{
PickerViewController *pvc = [[PickerViewController alloc] init];
[self presentViewController:pvc animated:YES completion:nil];
}
Now, I realize every time I call the next view controller I am creating a new instance of it, but I don't know how else to do it, I figure this is the main problem. As of right now, I expect when I leave the tableview for the picker view and return the console should log "New no of rows = x" but that doesn't happen.
I know val3 isn't used and my addNew: may not be the best, but I just need it to handle the basic logging mentioned above and I should be able to take it from there.
Been stuck on this for days
Create a property for TableViewController, and only create it the first time you present it,
- (IBAction)add:(id)sender {
if (! self.tvc) {
self.tvc = [[TableViewController alloc] init];
}
[self.tvc setValues:self.val1 :self.val2 :self.val3];
[self presentViewController:self.tvc animated:YES completion:nil];
}
It's not entirely clear from you question, whether it's this presentation or the one you have in the table view class that you're talking about. It also looks like you're doing something wrong in terms of presentation -- you're presenting the picker view from the table view controller, and also presenting the table view controller from the picker. That's not correct, you should present which ever controller you want to appear second, and that controller should use dismissViewControllerAnimated to go back, not present another controller.
In testAdd you don't need to create a new instance and present it. If you want to go back to the presentingViewController, just use dismissViewControllerAnimated .
And you will go one controller up in the stack.

Can't reload a collection view - null

I'm developing a simple app which downloads images from Dribbble, but I'm having problem reloading the data for my collection view. I have two views set up with ViewDeck, center is my main view which contains the collection view and another view contains table view with settings and from there I'm trying to call a method in the first view and reload data when item is tapped but it just doesn't work.
I tried to call the same method from the main window using button -> worked like a charm but from the second window it just doesn't update the data.
I tried to debug somehow and seems like my collection is null when the reload is called, no idea why.
SettingsViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"tap");
JKViewController *appDelegate = [[JKViewController alloc] init];
appDelegate.dataHasChanged = YES;
[appDelegate refresh];
[self.viewDeckController closeLeftViewAnimated:YES];
}
MainView
- (void)refresh{
NSLog(#"refresh");
if(dataHasChanged)
{
switch (listType) {
case 0:
[self refreshWithList:SPListPopular];
break;
case 1:
[self refreshWithList:SPListEveryone];
break;
case 2:
[self refreshWithList:SPListDebuts];
break;
case 3:
[self refreshWithList:SPListPopular];
break;
default:
[self refreshWithList:nil];
break;
}
dataHasChanged = NO;
NSLog(#"Should refresh");
}
NSLog(#"%d", [self->shots count]);
NSLog(#"Collection view: %#",self.collectionView.description);
NSLog(#"self.list: %#",self.list);
NSLog(#"List type: %d", listType);
}
This doesn't work :/, but when I call it from button in the MainView it works.
- (IBAction)changeList:(id)sender {
[self refreshWithList:SPListDebuts];
}
Does anyone know what could be the issue?
Edit - Solved
Getting the right instance of the centerViewController
JKViewController *mainController = ((UINavigationController*)self.viewDeckController.centerController).visibleViewController.navigationController.viewControllers[0];
The reason that you are not seeing your data being updated is because you are creating a new view controller and telling that to refresh. This new view controller has been initialized but not added to your view hierarchy. What you want to do is message the existing view controller like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"tap");
JKViewController *mainViewController = self.viewDeckController.centerViewController;
mainViewController.dataHasChanged = YES;
[mainViewController refresh];
[self.viewDeckController closeLeftViewAnimated:YES];
}
Also, please note that I have changed the variable name in my revision. Naming a UIViewController instance 'appDelegate' is very confusing.

Resources