UITextView Not Become Responding From Another UITextView Accessory View iPhone? - iphone

I am working on a message based iPhone app. I have a screen to reply to a received message. This screen contains two UITextViews like bottomTextView and topTextView.
topTextView is added as bottomTextView's InputAccessory view.
When the user enter into the screen topTextView has to becomeFirstResponder. It is showing but the cursor is not placed in the topTextView. The cursor is located in the textview bottomTextView. How to make topTextView become first responder with cursor in place?
Here is the code i have tried:
- (void)viewDidLoad
{
[super viewDidLoad];
bottomBarView = [[UIView alloc] initWithFrame:CGRectMake(0, 380, 320, 40)];
bottomBarViewImage.image = [UIImage imageNamed: #"toolbarbg~iphone.png"];
[bottomBarView addSubview: bottomBarViewImage];
[self.view addSubview: bottomBarView];
bottomTextView = [[UITextView alloc] initWithFrame:CGRectMake(35, 7.5, 210, 25)];
bottomTextView.delegate = self;
bottomTextView.backgroundColor = [UIColor clearColor];
bottomTextView.font = [UIFont fontWithName:#"Helvetica" size:14];
bottomTextView.scrollEnabled = NO;
[bottomBarView addSubview: bottomTextView];
topBarView = [[UIView alloc] initWithFrame:CGRectMake(0, 380, 320, 40)];
topBarViewImage.image = [UIImage imageNamed: #"toolbarbg~iphone.png"];
[topBarView addSubview: topBarViewImage];
topTextView = [[UITextView alloc] initWithFrame:CGRectMake(35, 7.5, 210, 25)];
topTextView.delegate = self;
topTextView.backgroundColor = [UIColor clearColor];
topTextView.font = [UIFont fontWithName:#"Helvetica" size:14];
topTextView.scrollEnabled = NO;
[topBarView addSubview: topTextView];
[bottomTextView becomeFirstResponder];
[bottomTextView setInputAccessoryView: topBarView];
}
-(void) textViewDidBeginEditing:(UITextView *)textView
{
if(textView == bottomTextView)
{
bottomTextView.scrollEnabled = NO;
[topTextView becomeFirstResponder];
}
}
The topTextView with topBarView is showing but the cursor is not placed in topTextView. Could you please help me to solve this issue? Thanks in advance.

I think it may be because you call [topTextView becomeFirstResponder]; in UITextView's delegate textViewDidBeginEditing:. So the topTextView only becomes first responder when you start editing bottomTextView. Try calling [topTextView becomeFirstResponder]; instead of [bottomTextView becomeFirstResponder]; in viewDidLoad. See how it goes. I'm not sure, but becomeFirstResponder may not call textViewDidBeginEditing:. Not sure it'll work, but worth the try...
EDIT :
I found a related problem here. It may be because the textView does not appear right away, so it can not become first responder. Here is the accepted answer, by #Tom :
My solution: check when the keyboard (and thus the accessory view)
appeared!
Step 1) Listen for the notification (make sure this code is read
before you want to receive the notification).
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(changeFirstResponder)
name:UIKeyboardDidShowNotification
object:nil];
Step 2) When the keyboard has appeared, you can set the textfield in
your inputaccessoryview to become first responder:
-(void)changeFirstResponder
{
[textField becomeFirstResponder]; //will return TRUE;
}

Related

UIModalTransitionStylePartialCurl acting strange with subclassed elements in iOS 5

I have a UIModalTransitionStylePartialCurl which is acting funky. My views UILabel and UIButton animate as if the labels frame is being changed all the time.
In iOS 4 or 6 it works statically. I've made a video of the bug on youtube.
I found an answer to this problem, but I don't quite understand the implementation. I alloc and init all of my elements in viewDidLoad, so where exactly is [self layoutIfNeeded]; going to help?
My code, if relevant is as follows (refactored):
- (void)viewDidLoad
{
[super viewDidLoad];
// Label
textLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 120, 280, 40)];
textLabel.text = #"Change password";
[self.view addSubview: textLabel];
// old password
oldPassword = [[UITextField alloc] initWithFrame: CGRectMake(20, 180, 280, 40)];
oldPassword.secureTextEntry = YES;
oldPassword.placeholder = #"Current Password";
oldPassword.returnKeyType = UIReturnKeyNext;
oldPassword.autocapitalizationType = UITextAutocapitalizationTypeNone;
oldPassword.delegate = self;
[self.view addSubview: oldPassword];
// New password
CGRect chosenPasswordFrame = oldPassword.frame;
chosenPasswordFrame.origin.y += 40;
chosenPassword = [[CustomTextField alloc] initWithFrame: chosenPasswordFrame];
chosenPassword.secureTextEntry = YES;
chosenPassword.placeholder = #"New Password";
chosenPassword.returnKeyType = UIReturnKeyGo;
chosenPassword.autocapitalizationType = UITextAutocapitalizationTypeNone;
chosenPassword.delegate = self;
[self.view addSubview: chosenPassword];
// Submit button
submitButton = [[UIButton alloc] initWithFrame:CGRectMake(20, chosenPasswordFrame.origin.y + chosenPasswordFrame.size.height + 20, self.view.frame.size.width - 40, 45)];
[submitButton setTitle:#"Submit" forState:UIControlStateNormal];
[submitButton addTarget:self action:#selector(changePassword) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview: submitButton];
self.view.backgroundColor = [UIColor colorWithPatternImage:[[AppTheme sharedTheme] changePasswordBackgroundImage]];
}
It looks like the setting of your view's frames is getting caught in the CATransaction being created by the partial page curl animation and being animated. Since the frames should never have been CGRectZero at least in the code you posted, this does seem to be a bug in iOS 5. Especially based on the number of up-votes that the answer you linked has received. And that answer describes the problem well.
Essentially, if you force the new view to lay itself out immediately by calling [self layoutIfNeeded] it forces the view system to realize that these are the current frame values not the ones to be animated to. And then even if this bug still tries to animate it's a non-op. Animating from frame A to frame A is at the very worst imperceptible. And since the "buggy" animation would finish at the same time as the curl animation it really (in practice) doesn't matter to you. With the exception of an inexplicable call to layoutIfNeeded in viewDidLoad.

App crashes when clicking on UISearchbar (searchDisplayController)

I am implementing the searchdisplay controller on the iPhone App, but will hit the following error when I try to click on the search bar (after a few tries)
Thread 1: EXC_BAD_ACCESS (code=1, address=0x30000008)
Snippet of my code as follows:
- (void)viewDidLoad
{
//Setting up the search bar for search display controller
UISearchBar *tempBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0, 34, 320, 44)];
self.sBar = tempBar;
[tempBar release];
self.sBar.delegate = self;
self.sBar.tintColor = [UIColor colorWithHexString:#"#b6c0c7"];
self.sBar.placeholder = #"Search DM friends";
self.searchDisplayController = [[[UISearchDisplayController alloc] initWithSearchBar:sBar contentsController:self]autorelease];
[self setSearchDisplayController:searchDisplayController];
[searchDisplayController setDelegate:self];
[searchDisplayController setSearchResultsDataSource:self];
self.searchDisplayController.searchResultsTableView.delegate = self;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = [[[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 78)]autorelease];
headerView.backgroundColor = [UIColor colorWithHexString:#"#ebe7e6"];
if (tableView != self.searchDisplayController.searchResultsTableView){
//Search
UILabel *tagFriendsTitle = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 320, 16)];
tagFriendsTitle.font = [UIFont boldSystemFontOfSize:14];
tagFriendsTitle.backgroundColor = [UIColor clearColor];
tagFriendsTitle.text = #"Who should see this? Tag them!";
[headerView addSubview:tagFriendsTitle];
//THIS IS WHERE I GET MY EXC_BAD_ACCESS error
[headerView addSubview:self.sBar];
[tagFriendsTitle release];
}
return headerView;
}
I am not sure which part of my code is causing the error, but it seems that the sBar deallocated from memory when I try to add it to header subview? But I am not sure why I needed to click on the search bar multiple times before that happens.
This is how it looks on the iPhone, the searchbar forms part of the headerview
go to product>edit schems> enable nszombie objects and see what's the prblem there
If this is an assign property, you should probably change it to a retain property. And don't forget to set the property to nil in dealloc and viewDidUnload.

UITextView, user scrolls uitextview but then it snaps back to original position, whats wrong?

I currently have a UITextView which is contained in a UIViewController using the following code:
UIViewController *container = [[UIViewController alloc] init];
container.view.frame = CGRectMake(0, 0,
[UIScreen mainScreen].bounds.size.width, 1000);
//[UIScreen mainScreen].bounds.size.height
container.view.userInteractionEnabled = YES;
container.view.clipsToBounds = YES;
UIImageView *imgView = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"myImage.png"]];
imgView.frame = container.view.frame;
imgView.userInteractionEnabled = YES;
[container.view addSubview:imgView];
[imgView release];
UITextView *textContained = [[UITextView alloc]
initWithFrame:CGRectMake(0, 0, container.view.bounds.size.width, 1000)];
//container.view.bounds.size.height
textContained.font = [UIFont fontWithName:#"Calibri" size:14];
textContained.scrollEnabled = YES;
textContained.editable = NO;
textContained.textColor = [UIColor whiteColor];
textContained.backgroundColor = [UIColor clearColor];
textContained.font = [UIFont boldSystemFontOfSize:14];
textContained.userInteractionEnabled = YES;
textContained.alwaysBounceVertical = YES;
textContained.contentSize = CGSizeMake(container.view.frame.size.width,
container.view.frame.size.height);
I then set my UItextView text property with some text, which extends past the current screen size. I then add my UITextView to my container using the following code.
switch (indexPath.row) {
case 0:
textContained.text = #"LOTS AND LOTS OF TEXT";
[container.view addSubview:textContained];
[self.navigationController pushViewController:container animated:YES];
[textContained release];
break;
default:
break;
}
[container release];
When I test this code, the text appears just fine in the UITextView and everything looks ok. But the problem is when I try to scroll down to see the remainder of the text. Everytime I scroll down the UITextView scrolls back in to its original position. I have tried several ways to get this to work, but I think I need some fresh eyes to see what I'm doing wrong.
Any help is greatly appreciated.
First, you don't want to set the contentSize of a UITextView, since it is determined by the length of text automatically.
Try to make the height of textView smaller. For example:
UITextView *textContained = [[UITextView alloc]
initWithFrame:CGRectMake(0, 0, container.view.bounds.size.width, 50)];
And give it more text, like:
textContained.text = #"LOTS AND LOTS OF TEXT\nLOTS AND LOTS OF TEXT\nLOTS AND LOTS OF TEXT\n\nLOTS AND LOTS OF TEXT\nLOTS AND LOTS OF TEXT\n";

UIScrollView with UITapGestureRecognizer and UIPageControl

I'm creating a horizontal scrolling tableview containing images. I have the swiping functionality working great, and am able to add the images to the scrollView as so in cellForRowAtIndexPath:
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, tv.frame.size.width, 78)];
[scrollView setContentSize:CGSizeMake(700, 78)];
UIImage *footImage = [UIImage imageNamed:#"Foot.png"];
UIImageView *footImageView = [[UIImageView alloc] initWithImage:footImage];
footImageView.frame = CGRectMake(0, 0, 80, 78);
footImageView.userInteractionEnabled = YES;
[scrollView addSubview: footImageView];
UIImage *handImage = [UIImage imageNamed:#"Hand.png"];
UIImageView *handImageView = [[UIImageView alloc] initWithImage:handImage];
handImageView.frame = CGRectMake(90, 0, 80, 78);
handImageView.userInteractionEnabled = YES;
[scrollView addSubview: handImageView];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(highlightImage)];
[scrollView addGestureRecognizer:tapGesture];
NSLog(#"tapGesture added to scrollView");
[[cell contentView] addSubview:scrollView];
pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, 50, tv.frame.size.width, 50)];
[pageControl setNumberOfPages:4];
[[cell contentView] addSubview:pageControl];
My tapGesture is registering with the selector, hightlightImage, and just logging that its calling this method correctly.
- (void) highlightImage
{
NSLog(#"tapping tapping");
}
What I REALLY am working for is the ability to highlight/select these images if tapped, and highlight/deselect them if tapped again. I will have another button on screen that will navigate to the next page (irrelevant here).
Am I going down the right path here? Obviously I will populate an NSArray of UIImages and populate the scrollView that way, but just spiking it out for now. If someone could give me some direction or an example of how to make each button separately selectable/de-selectable, that would be GREAT:)
Use UIButton instead of UIImageView.
It's got built-in selected functionality.
get rid of your gestures and add highlightImage as the action to every button.
make your highlightImage into highlightImage:(id)sender
sender should be a button so you can just do
[sender setSelected:YES];

iPhone: Add "loading" subView

I am wanting to show a simple loading dialog when certain things are happening in my app. I figured I would just create a new view, add a label to that, and then set that view to a subView of my current view.
When doing this, I don't see anything!
Here is how I am writing my method:
- (void)showLoading {
UIView *loading = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
loading.backgroundColor = [UIColor blackColor];
UILabel *txt = [[UILabel alloc] initWithFrame:CGRectMake(198, 9, 94, 27)];
txt.text = #"Loading...";
txt.textColor = [UIColor whiteColor];
[loading addSubview:txt];
[super.view addSubview:loading];
[super.view bringSubviewToFront:loading];
[loading release];
[txt release];
}
Am I doing this completely wrong?
EDIT:
I added it to the viewDidLoad method, and it works how I want:
loading = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
loading.backgroundColor = [UIColor blackColor];
UILabel *txt = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 94, 27)];
txt.text = #"Loading...";
txt.textColor = [UIColor whiteColor];
[loading addSubview:txt];
[txt release];
[self.view addSubview:loading];
[self.view bringSubviewToFront:loading];
But when loading it from a method, it seems to lag, and not show up for a bit.
Although this doesn't directly answer your question, I'd recommend grabbing MBProgressHUD from GitHub and using that in place of a static label. Looks better, less code for you to directly maintain, etc. You can find it at http://github.com/matej/MBProgressHUD
The way I use it is by creating a subclass of UITableViewController and defining a handful of methods to show and hide the HUD view. From there, I call each relevant method when I'm loading or done loading.
Specifically, I have four methods: -hudView, -showLoadingUI, -showLoadingUIWithText:, and -hideLoadingUI.
-hudView creates a new MBProgressHUD object if one doesn't already exist, and adds it to the current view ([self.view addSubview:hudView]).
-showLoadingUI calls -showLoadingUIWithText: with a default title, -showLoadingUIWithText: just unhides the MBProgressHUD and sets a label value for it (self.hudView.labelText = #"foo";).
-hideLoadingUI hides the hudView ([self.hudView hide:YES]).
First, I don't think UIView has method called init. You may just call the super of it. The appropriate method you should call is - (id)initWithFrame:(CGRect)aRect . The frame is the position, the size of the View you want to display. More here
Another thing is why you call [super.view addSubView:], I think it should be self.view, isn't it?