I have a uiswitch view in a static table. I am trying to retrieve it via its tag in the viewdid load method. For some reason it always shows null. I do it with the viewWithTagMethod.
UISwitch* switch = (UISwitch*)[self.view viewWithTag:tag];
[switch setOn:[value boolValue] animated:YES];
Static table view contents are not loaded until after the super implementation of viewWillAppear:animated: has been called. Move your code to a later point and you should be fine. Alternatively, just use an outlet.
Related
I have two View Controllers: SavePopOverVC and MainVC. I also have a nib file called SavePopOver. SavePopOver has three items, a UIButton, a UIImage and a UITextView. The image and text view have outlets to property fields in SavePopOverVC called captionImage and captionTextView respectively. The button has an outlet to an IBAction in SavePopOverVC.
In MainVC.m I have the following two lines in my class extension.
SavePopOverVC *spvc;
UIPopoverController *popover;
In my viewDidLoad of the same file I have the following lines relating to my popover.
spvc = [[SavePopOverVC alloc] initWithNibNamed:#"SavePopOver" bundle:nil];
popover = [[UIPopoverController alloc] initWithContentViewController:spvc];
In my function that displays my popover, also in MainVC.m, I have the following lines.
[popover setPopoverContentSize:CGSizeMake(600,200)];
[popover presentPopoverFromRect:_header.frame inView:self.view permittedArrowDirection:UIPopoverArrowDirectionAny animated:YES];
[((SavePopOverVC *)popover.contentViewController).captionTextView setText:#"Some text here"];
However, captionTextView is nil when I make the setText: call. The app doesn't crash but the text isn't set. After the popover is displayed and I click on the UIButton to save the string typed in captionTextView I get the string just fine. So, I know the two are ultimately linked correctly, but how can I set captionTextView from when I display the popover?
If it is worth noting, I'm developing solely for iPad with this one.
It is most likely nil because its view isn't loaded at the time you set the text. Unlike most other modern languages, in Objective-C calling a method on a nil object doesn't cause an exception, it just does nothing.
To solve this, you can create a custom NSString property in your SavePopOverVC, e.g.
#property (nonatomic, copy) NSString *caption;
Before you call presentPopoverFromRect:, assign a value to this property. Inside SavePopOverVC, override viewDidLoad and set the captionTextView.text = self.caption;
There might be people who disagree with me, but I don't recommend exposing UI controls as properties in a view controller. This behaviour is one of the reasons for that.
This question already has answers here:
Passing data between view controllers
(45 answers)
Closed 8 years ago.
I have two view controllers.
First one is Custom view controller that loads the images from asset library.
Second view controller shows the full size of selected image with cancel & Delete button
I have used the below code for delete the selected image from custom view controller.
customviewcontroller.m
-(void)deleteItemsFromDataSourceAtIndexPaths:(NSArray *)itemPaths
{
//here i want to control the delete option when cancel pressed
NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
for (NSIndexPath *itemPath in itemPaths) {
[indexSet addIndex:itemPath.row];
}
[self.selectedAssets removeObjectsAtIndexes:indexSet];
}
/* call the delete function*/
- (void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *selectedItemsIndexPaths = [self.collectionview1 indexPathsForSelectedItems];
[self deleteItemsFromDataSourceAtIndexPaths:selectedItemsIndexPaths];
[self.collectionview1 deleteItemsAtIndexPaths:selectedItemsIndexPaths];
}
This working fine for delete the selected image from custom view controller.
but It works also cancel. Now, I want to control deletion on cancel.
kindly help me to solve this.
I have already tried using button tag for identify which button was pressed. but can't control in custom vc
secondview.m
- (IBAction)CancelPhoto:(id)sender{
[Cancel setTag:1]; //set tag value at cancel
}
There are several ways to pass date between view controllers. I'm giving you a very simple solution as per your requirements:
Assuming you have all your images in a mutable array in first view controller.
NSMutableAray *imagesArray;
Make a property images array of NSMutableArray type in second view controller.
#property(nonatomic, strong) NSMutableAray *imagesArray;
assign your array to property while pushing/presenting view
secondController.imagesArray = imagesArray;
On delete event remove that image from array.
[self.imagesArray removeObjectAtIndex:selectedIndex];
dismiss/pop your second view where ever you want and refresh your first view controller in viewWillAppear of viewDidAppear method.
As you have passed reference of your main images array, both classes (view controllers) share same array through pointer and a change in array from either side will be reflected in both screens
There are 3 ways (in my opinion):
Delegate
Notification
In case: you are using database, just remove image url and reload data
It's this case again:
I wish to fill the prototype cells with the names of the friends selected in the UIPickerView over there. I have programatically filled the picker with the string representation of my Player object data, and set its properties using the delegate functions.
The "New Game Friends View" you see here has its own viewcontroller subclass, as has the table view, which I attempt to embed into a UIView on the "New Game Friends View". The table view IS an instance of my WHGFriendTableViewController class. I know this because this function does not throw any exceptions:
- (IBAction)addBtnClicked:(id)sender {
WHGFriendTableViewController* tabView = (WHGFriendTableViewController*) [[self childViewControllers] objectAtIndex:0];
NSInteger row = [friendPicker selectedRowInComponent:0];
[[tabView selectedFriends] addObject:[[self friendList] objectAtIndex:row]];
[[tabView tableView] reloadData];
}
Now the problem is: while the function above does not throw any exceptions, it still does not work. It appears that nothing really happens when I insert the objectAtIndex:row into the NSMutableArray selectedFriends (which is a property) in the table view's view controller.
This:
NSLog(#"New length: %d", [[tabView selectedFriends] count]);
prints 0 after inserting the new object. I have no idea why. Printing the count of [self friendList] gives three, just as I expect. The reloadData message does not make anything appear in the table view.
Any ideas why I cannot insert new data into the table view with my code, when this seems to be working with no exceptions whatsoever? Thanks in advance!
Have you alloced & init your NSMutableArray selectedFriends?
Also have you set the dataSource and delegate of your table view?
Using storyboard, I have a table view controller containing multiple dynamic prototype cells. One of the cells is a custom dynamic prototype cell (for which I created a subclass) containing a label and a switch. I have the action for the switch wired to an action method (say switchChanged:) in the view controller. In cellForRowAtIndexPath, I configure and return the cell appropriate for the specified index. So far so good.
The problem: my application has multiple instances of these custom cells, so how do I differentiate which switch has changed? One thought is that in the view controller I can create a member switch for each cell and link them to a specific cell switch when cellForRowAtIndexPath is called for the first time. Then I can use these member switches to compare with the switch that is passed into switchChanged:.
I know that I can try it and get an immediate answer, but I was hoping for a discussion of how other developers do what I am trying to do. Is this the best/worst/ok approach and what are practical alternatives?
Regards,
--John
I had this situation once (not with switches, but I believe it applies just the same). I've managed to get around it by subclassing the object class and adding the required properties/methods inside the subclass.
When calling the action, your sender will be the subclass, and you can access your added code there.
I don't know if it is the case, but if you're only trying to change a value, you should use bind the switch value to the property when creating the object. It will not even need an IBAction to call.
EDIT: Example:
#interface MySwitch : UISwitch
#property (nonatomic, assign) NSUInteger someProperty;
#end
Then, every time you create a cell, you can set "someProperty" to anything you want.
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
// yada yada yada...
UITableViewCell *cell;
// yada yada yada...
[cell.myLinkedSwitch setSomeProperty:indexPath.row];
return(cell);
}
Unless you're not creating your cells using the tableView:cellForRowAtIndexPath: method. Then you probably should use bindings to get your value to the right place.
Instead of adding a separate subclass, I just stored the row in each button Disabled Title property. This worked very will with little effort. This first code is in the CellForRowAtIndexPath:
NSString *strRow = [[NSString alloc] initWithFormat:#"%i",useRow];
[btnPreferredChk setTitle:strRow forState:UIControlStateDisabled];
Then my action method for the button uses that value to perform the appropriate activity.
- (IBAction)goStorePick:(id)sender
{
UIButton *useButton = [[UIButton alloc] init];
useButton = sender;
NSInteger *storeRow = [[useButton titleForState:UIControlStateDisabled] integerValue];
NSString *CMIMsg = [[NSString alloc] initWithFormat:#"goStorePick Method Executed at Row: %i", storeRow];
[self shwMessage:CMIMsg];
}
This worked well for me.
I have a tableview with UITextFields to build a form. I then have a button in the toolbar which launches a modal view controller to select some data which is then passed back to the tableview. However, the new data that was selected does not get refreshed into the UITextField using textField.text = valueReturnedFromModal syntax. Is there something I'm missing?
I see that the data is being returned properly from the modal so that is not the issue. I'm just having trouble forcing the UITextField to refresh with the new data. I've tried forcing a reloadData on the tableview as well.
So from the modal view, here's the code that passes data back:
- (void)doneAccountSelection:(id)sender
{
[delegate didSelectAccount:currentAccount];
[self dismissModalViewControllerAnimated:YES];
}
and here's the actual method in the delegate:
- (void)didSelectAccount:(SFAccount *)selectedAccount
{
//Ensure a valid deal exists for the account to be attached to
[self createDealObjectIfNeeded];
//Set the deal account
[self.deal setAccount:selectedAccount];
//Refresh the text fields
//Tag 3: Account Name field
UITextField *acct_name = (UITextField *) [self.view viewWithTag:3];
[acct_name setText:self.deal.account.field_acct_name_value];
//Tag 4: Account City field
UITextField *acct_city = (UITextField *) [self.view viewWithTag:4];
[acct_city setText:self.deal.account.field_acct_city_value];
//Save the context changes. A new deal gets created above if one does not exist.
if ([self saveModel]) NSLog(#"Acct object created, attached to deal successfully!");
[self.tableView reloadData];
}
Would you mind posting the code that sets the text fields data and the code that passes the data back to the table view?
Answer:
It appears that you are properly setting the data, however, you are dismissing the modal view controller after sending the delegate message. In this scenario, the table view is not even created until after the dismissModalViewControllerAnimated: has ended. Which means the textfields are NULL until the view is present. What I suggest is call
[self dismissModalViewControllerAnimated:YES];
as the first line in the didSelectAccount: delegate method. This would dismiss the modal view and then continue on with your setting the data to valid textfields as -viewWillAppear: / -viewDidAppear: would have already been called. Everything seems ok it's just the order that may be tripping you up. Although
-dismissModalViewControllerAnimated:
is passed to its parent if a view controller does not have a modal view (because it is the modal view), it seems more appropriate to call this method in the delegate method where you will eventually manipulate the view due to new data, etc.
use this after getting Value in text field:
[self.tableView ReloadData];
After some serious debugging found that self.account was being used in cellForRowAtIndexPath to set the initial UITextField values within the UITableViewCell. Then after modal selection completed, I was only updating the account reference for the deal object and not updating the self.account object.
I then added to this by creating a new method called updateTextFieldsAfterModalFinished and moved the code to update the UITextFields there. This method was then called from didSelectAccount which is the delegate method for modal view that is dismissed. Things are now working as expected and the UITextFields get updated after modal selection is finished.