How to set cursor position for UITextView inside UITableViewCell - objective-c

We are doing a validation in a UITableViewCell. The cell has a textView and a custom button on clicking which a pop over containing a UIDatePickerView should open & the user will select the date. Here selecting the date is mandatory. So we did a validation using the below code. In the textViewBeginEditing delegate method of the textView inside the cell in the immediate next row. i.e when the user clicks on the textView in the next row the previous row values will be validated.
Here the validation seems to be working but the cursor still blinks in current cell and do not move to the previous cell that is being validated.
UITableViewCell* myCell = (UITableViewCell*)textView.superview ;
UITextView *txtviewMycelltext;//=[[UITextView alloc]init];
for (UIView *view in myCell.subviews)
{
if([view isKindOfClass:[UILabel class]])
{
UILabel *lbl=view;
lbl.text=[lbl.text stringByReplacingOccurrencesOfString:#"." withString:#""];
int tablerowindex=[lbl.text intValue];
NSLog(#"%#",lbl.text);
break;
}
if([view isKindOfClass:[UITextView class]])
{
txtviewMycelltext=view;
}
}
inttablerowindex-=1;
if(inttablerowindex>0)
{
if([[arrActionvalues objectAtIndex:inttablerowindex1]objectForKey:KEY_FOLLOWUPDATE]==EMPTYSTRING)
{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle: #"Alert"
message: ALERT_FOLLOWUPDATE
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
// UITableView *mytable=(UITableView *)((textView.superview).superview).superview;
UITableView *myTable=(UITableView*)[[myCell superview]superview];
NSIndexPath *indexPath = (NSIndexPath*)[myTable indexPathForCell:
(UITableViewCell*)textView.superview.superview];
UITableViewCell *previousCell = (UITableViewCell*)[myTable cellForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section]];
for (UIView *view in previousCell.subviews)
{
NSLog(#"%#",view);
if([view isKindOfClass:[UIView class]]) {
UIView *subView=view;
for(UIView *view2 in subView.subviews)
{
if([view2 isKindOfClass:[UITextView class]]) {
UITextView *txt=view2;
[txtviewMycelltext resignFirstResponder];
[txt becomeFirstResponder];
break;
}
}
}
}
}
}
Please let me know what needs to be done to get the cursor position to the correct cell.

It is not very clear from you code, but, I am guessing you are performing your validations inside textViewDidEndEditing.
textViewShouldEndEditing is the appropriate delegate method to perform validation of the text view contents. You can return NO if you want to prevent the switching of focus from the current text view.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UITextViewDelegate_Protocol/Reference/UITextViewDelegate.html#//apple_ref/occ/intfm/UITextViewDelegate/textViewShouldEndEditing:

Related

NSTableViewCell selectedRow number for IBAction click

I'm running into a simple problem but have yet to find an optimal solution. I have a view based NSTableView that is loading it's cell views from different xibs. My table view is dynamic and based on user input I will dynamically add and remove rows ultimately adjusting the table data source. Each one of my NSTableCellViews have a button in it and I link the IBAction click handler to the NSView that holds the table view. What I need to do is get the row number for the button that was clicked in the table view so I can process the logic. I am able to do this successfully in : tableViewSelectionDidChange:(NSNotification *)notification
Here is how I do it:
- (void)tableViewSelectionDidChange:(NSNotification *)notification {
NSTableView *tableView = [notification object];
NSInteger selectedRow = [tableView selectedRow];
}
This works perfectly for a user actually clicking the row. Now when I move the NSButton IBAction and link it in the NSView as follows:
- (IBAction)buttonClickHandler:(NSButton *)sender {
NSInteger selectedRow = [self.tblView rowForView:sender];
NSLog(#"%ld", (long)selectedRow);
}
I based this approach from this selected answer.
I also tried this:
- (IBAction)buttonClickHandler:(NSButton *)sender {
id representedObject = [(NSTableCellView *)[sender superview] objectValue];
NSLog(#"%#", representedObject);
}
//My configuration
- (void)configureView {
[self.view setFrame:[self bounds]];
[self addSubview:self.view];
[self.view setWantsLayer:YES];
[self.view setTranslatesAutoresizingMaskIntoConstraints:NO];
self.tblView.delegate = self;
self.tblView.dataSource = self;
[self.tblView setIntercellSpacing:NSMakeSize(0, 0)];
[self.tblView registerNib: [[NSNib alloc] initWithNibNamed:#"ParentCellXib" bundle:nil] forIdentifier:#"ParentCell"];
[self.tblView registerNib: [[NSNib alloc] initWithNibNamed:#"ChildCellXib" bundle:nil] forIdentifier:#"ChildCell"];
[self.tblView registerNib: [[NSNib alloc] initWithNibNamed:#"HeaderCellXib" bundle:nil] forIdentifier:#"HeaderCell"];
}
But the represented object returns null. If it's worth mentioning, I've set my File's Owner as the View that holds the tableView so I can link the IBAction and I've subclassed the TableCellView to a different class. However, I don't think this is part of the problem as far as I can see. Is there a simple solution to reliably give me the selectedRow number based on a button click in that cell? Both approaches I tried above return -1 and null respectively.
I would set the row in NSButton's tag property:
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
SomeTableCellView *cell = [tableView makeViewWithIdentifier:#"cell" owner:self];
if (cell == nil) {
cell = // init some table cell view
cell.identifier = #"cell";
}
cell.button.tag = row;
[cell.button setTarget:self];
[cell.button setAction:#selector(buttonAction:)];
}
- (IBAction)buttonAction:(id)sender {
NSLog(#"row: %d", sender.tag);
}
Try This
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
yourCustomeCell *aCell;
NSString *aStrIdentifier = #"yourIdentiFier";
aCell = (yourCustomeCell *)[tableView dequeueReusableCellWithIdentifier:aStrIdentifier];
//you have to set your indexpath
objc_setAssociatedObject(aCell.btnUpload_or_Add, #"objBtn", indexPath, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[aCell.YourButton addTarget:self action:#selector(yourButtonActiontapped:) forControlEvents:UIControlEventTouchUpInside];
return aCell;
}
-(IBAction)yourButtonActiontapped:(UIButton *)sender{
NSIndexPath *aIndPath = objc_getAssociatedObject(sender, #"objBtn");
NSLog(#"row:%#",aIndPath.row);
}
also you have to import #import <objc/runtime.h>
another way to get row in IBAction is TAG but objc is better option insted of TAG.
Create a subclass of UIButton and add a property for NSIndexPath for the button. Use this button in cellForRowAtIndexPath method. assign the index path of the cell to that of index path of the button.
On Tap, get the index path from its sender. In your case index path of that button.

Unable to Get View Class in the top

I am trying to get current view open in my code using this code in delegate while handling Push Notification
NSArray *views = window.subviews;
NSLog(#"views: %#", views);
UIView *topview=[views lastObject];
when is click on topview and see using below tool (eye mark) it shows the current view
open .
But when i am try to get its kind of class using below two method none of these work
for(UIView *view in window.subviews)
{
if([view isKindOfClass:[MyClass class]])
{
NSLog(#"view is a MyClass\n");
}
}
or
if ([topview isKindOfClass:[MyClass class]])
{
NSLog(#"topview is a MyClass\n");
}
else
{
NSLog(#"topview is NOT a MyClass\n");
}
How can i get my visible view name of kind of class.
self.navigationController.viewControllers returns a UIViewController* array, not a UIView* array.
So, for your first solution:
for(UIViewController *viewController in self.navigationController.viewControllers)
{
if([viewController.view isKindOfClass:[MyClass class]])
{
NSLog(#"view is a MyClass\n");
}
}
will work.
For the visible UIViewController*, you can use:
UIViewController* viewController = self.navigationController.visibleViewController;
For the topmost view:
UIView* topmostView = [[[[UIApplication sharedApplication] keyWindow] subviews] lastObject];

All UITextFields in TableView

I have had some problems with checking if all UITextFields where filled in in my UITableView with Custom UITableViewCell classes
I was trying to do something with this sort of code:
for (UITextField* textField in self.view.subviews ){
NSLog(#"Text: %#", textField.text);
}
And this is the error:
-[UITableView text]: unrecognized selector sent to instance 0x10b034400
Oke, so I seem to be trying to get the UITableView say its text value, so that is not good. But how can I get the TableViewCell's TextFields? So I can check if the user filled in everything and it can save the information.
Grz
You need to get reference to UITableViewCell and do the enumeration on cell.contentView, all controls are stored on contentView cell property, not view directly. All course you should do check if the view is type of UITextField if you have some other controls than UITextField on cell.
The other thing is that you are not able to get UITextField reference for the cell which are not visible because they will be most likely dequeued.
This gives you all visible table view cells and you just need to enumerate it:
NSArray *arr = [self.tableView visibleCells];
for (UITableViewCell *cell in arr) {
for (UIView *v in cell.contentView.subviews) {
if ([v isKindOfClass:[UITextField class]]) {
UITextField *textField = (UITextField *) v;
NSLog(#"Text: %#", textField.text);
}
}
}
that because view's subviews are not necessarily UITextField objects, try this:
for (UIView *subview in self.view.subviews //be sure you are looping through the right view){
if ([subview isKindOfClass:[UITextField class]]) {
UITextField *textField = (UITextField *) subview;
NSLog(#"Text: %#", textField.text);
}
}
if it is in iOS 7, Your textfields should be in the first view in Cell's subviews
for (UITextField* textField in self.view.subviews[0] ){
NSLog(#"Text: %#", textField.text);
}

didSelectRowAtIndexPath - colorText change not updated instantaneously

I'm trying to change the text color in a custom label in a custom UITableViewCell.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//////////////////////
// Unselect the prevoius selected Cell and select this one
WSLanguageTableViewCell *aPreviousSelectedCell= (WSLanguageTableViewCell*)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:selectedRow inSection:0]];
aPreviousSelectedCell.languageLabel.textColor = [UIColor lightGrayColor];
// Select the new one
WSLanguageTableViewCell *aSelectedCell = (WSLanguageTableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];
aSelectedCell.languageLabel.textColor = [UIColor colorLanguageCellLanguageLabelText];
selectedRow = indexPath.row;
///////////////////////
// Get the new language
PFObject* languageObject = [self.objects objectAtIndex:indexPath.row];
NSString* language = [languageObject objectForKey:kWSLanguageNameKey];
//////////////////////
// Check if it's setup -- if not, then show alert
if (![[languageObject objectForKey:kWSLanguageIsSetupKey] boolValue]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:kPromptChangeLanguageNotSetup message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
return;
}
//////////////////////
// Check if it's the current language -- only change if not
if (![language isEqualToString:[[WSWordlistManager shared] languageTarget]]) {
// Show HUD view
AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication]delegate];
[appDel showGlobalProgressHUDWithTitle:kLocalizedChangingLanguage];
//////////////////////
// Load the wordlist
[[WSWordlistManager shared] loadWordlist:language completion:^() {
//////////////////////
// Add the language to user (and vice versa) in DB
[WSUserManager addLanguage:language forUser:[PFUser currentUser]];
///////////////////
// Reload User Words
WSDatabaseManager* databaseManager = [[WSDatabaseManager alloc] init];
[databaseManager retrieveUserWordlistForCurrentUserWithCallback:^(NSError *error) {
// Dismiss the HUD
AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication]delegate];
[appDel dismissGlobalHUD];
// Navigate to root
[self.navigationController popToRootViewControllerAnimated:YES];
}];
}];
}
}
The problem is, the color change is delayed for a while. If I take out everything below the 6 lines setting the textColor of the two cells, the change is instantaneous. What method(s) do I run right after changing the textColor so it displays?
Check UILabel's highlightedTextColor property. This is correct way to change color of selected cell's label.

Keep UIAlertView displayed

I have a UIAlertView with a textField on it and two buttons: Save & Cancel. When the Save button is tapped I am checking if the text field isn't empty and after if it is I simply want to change the textFields placeholder to: #"enter a name please" and KEEP the alert view on screen. However it is automatically dismissed.
How do I override that?
Add a target to the textfield in a subclassed alertView. You can subclass the alertView and not dismiss as described in this post
[[alertView textFieldAtIndex:0] addTarget:self action:#selector(textFieldDidChange) forControlEvents:UIControlEventEditingChanged];
Then write a function called textFieldDidChange that checks the current textfield of your alertView and set a boolean value so you know whether or not to dismiss the alert.
- (void) textFieldDidChange
{
NSString *alertViewText = [[alertView textFieldAtIndex:0] text];
if ([alertViewText isEqualToString:#""]) {
[alertView setMessage:#"Enter a name please."];
} else {
[alertView setMessage:#"Default Message"];
}
}
* Alternatively, I would suggest disabling "Save" when it is empty and not have to subclass. *
- (void) textFieldDidChange
{
NSString *alertViewText = [[alertView textFieldAtIndex:0] text];
if ([alertViewText isEqualToString:#""]) {
[alertView setMessage:#"Enter a name please."];
for (UIViewController *view in alertView.subview) {
if ([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view;
if ([[[button titleLabel] text] isEqualToString:#"Save"])
[button setEnabled:NO];
}
}
} else {
[alertView setMessage:#"Default Message"];
for (UIViewController *view in alertView.subview) {
if ([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view;
if ([[[button titleLabel] text] isEqualToString:#"Save"])
[button setEnabled:YES];
}
}
}
}