Make a UITextView object editable - iphone

This is obviously an extremely "noobish" question. I'm aware that UITextView has a Boolean editable property, (since I'm not entirely illiterate) so the answer to my question seems really straightforward. But...
I create a UITextView programatically like this:
UITextView* input = [[UITextView alloc] initWithFrame: CGRectMake(0, 0, 100, 30)];
input.backgroundColor = [UIColor whiteColor];
input.editable = YES;
input.text = #"Type something here...";
[input setUserInteractionEnabled: YES];
....
[mainView addSubview: input];
But when I run the iPhone simulator with Xcode, clicking on the input field doesn't do anything. I can't input any text, the virtual keyboard doesn't appear, etc.
So, what am I doing wrong here? Why isn't the UITextView object actually editable in the Xcode iPhone emulator?

I just ran your code in the viewDidLoad command of a sample app that I test code in and it works fine. In my case, I have a UIWebView that I added via Interface Builder which your UITextView pops on top of. I click it and the keyboard pops up.
Is it possible that you may be creating some other object that is begin added to the view after your textfield that is covering it up? Any other view objects being added in the .... part of your sample code?

Related

iPhone the beginner's application [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Short pre-introduction to a problem:
I applied to a position of iOS developer. For this position they don't require knowledge of Objective-C or iOS development. The requisites are a good experience with C/C++ and development for Linux platform.
Problem:
After the end of interview I got a task (with words that it's easy to impelement, is it?) and I can't understand whether it's so.
Interviewer has showed me an application on his iPhone that looked like:
Pressing/dragging that button leads to appearance of such bar:
He could scroll it and drag on the screen. When he had pressed the control button, bar disappeared.
I want to ask for excuse in advance, because I feel myself like a person who wants his job to be done by others. But I just want understand how I can approach to this problem. Cocoa library is a big and a new beast to me. Which classes/elements from it is it better to use to reach this aim? I programmed before with Qt, Tkinter, WinAPI (gui programming) for desktop but it doesn't help me a lot here.
I need to code something similar like the interviewer has showed me. I tried to find something in the internet similar to this, but without success.
So, I just want to know for which classes it's better to look for in Cocoa library.
And, if I failed to take something into consideration I would be glad (happy) to hear your notes.
Thanks in advance for any replies!
SOLVED
I want to thank everyone who replied and didn't leave me to sink into this unknown sea.
After a week of exploring I got what I wanted:
Source code: (I apologize, but I can't copy-paste code from virtual mac os machine)
Now I understand how too-wide and silly is my question, but anyway perhaps it helps someone to start out. Also one book helped me a lot.
There is no required understanding of Objective-C, but the interviewer wants you to create a simple application and return it to him? Interesting interview.
As for your question. The classes I see being needed here (aside the AppDelegate and a UIViewController of your choice) are:
UIButton
UIScrollView
UIImageView
The button's use here is obvious. The scrollview is again obvious. The imageview would be the icons inside the scrollview.
Allright - just to give you some guidance on what to start with and how to proceed so that you don't get lost in the great wide world of cocoa ...
And assuming that you are familiar with programming and have some decent experience in the c++ and java worlds ...
Open xcode.
Go for blank view based app. Single view application would do. Go for Automatic Reference Counting (ARC).
xcode creates a template for you with an application delegate (which you would not need for this task)
A view controller is created and a xib/nib file for an iPhone view. (ignore the ipad view if any).
Add to your view controllers so called IBAction methods. One for the top button and one for the others. An action is supposed to be called when a button is pressed (and other events which you don't need).
Properly defined you will see that action in the interface builde when editing the xib file. Add a button and connect it with this action (touch up inside would be best I think).
Compile this. When your button is pressed the action is executed. Set a breakpoint there to make sure that it got called.
Now, in this action, you either call a newly created method showScroller and hideScroller. And create those methods.
Now it gets a bit more complicated.
In showScroller you would have to ...
create a UIScrollView. (alloc it and init it)
create a number of UIButtons. (no alloc withot its init in objective-c)
set your second IBAction method as target for the buttons.
Position the buttons within the UIScrollView accordingly.
Position the UIScrollView nicely under the top button.
add the UIButtons as subview to the contentview of the Scroll view.
add the scroll view as subview to self.view (that is the underlying view, the grey thing in the interface builder).
In hideScroller you would have to ...
remove the UIScrolView from the view. For that you could either remove all subviews from self.view or you would have to keep a reference to the scroll view within your view controller in some instance variable. Pretty similar to C++ and Java which you know already.
Alternative to the scenario described above you could create all views within interface builder and pre-define the scroll view as hidden in IB (interface builder) and in showScroller and hideScroller you would just have to set its .hidden property to YES or NO. But I've got a guts feelting that with your background you should and could do this programmatically instead of hasseling with how IB connects into your code.
In the event that you really run into that trap and don't get the top most button properly connected to your code, then create that button programmatically too.
Ah, I forgot. The right place to create all those UI elements would be the viewDidLoad method of the ViewController class. There is an empty one generated already in your empty xcode template. Just enance it following the [super viewDidLoad]; call.
Have a look at this:
http://www.cocoacontrols.com/platforms/ios/controls/aurosetteview
When you press a button, the items show up and when you press again, it closes.
The source code is within the library. Use it to read up.
For your case, you need to include the scrollview as well.
Here you go:
Open XCode and create a new project. Choose iOS Empty Application template.
Go to menu, choose File, New File, Objective-C class. Name it RootViewController and choose a subclass to be UIViewController
Go to your app delegate .m file (If your project name was Test, this file is TestAppDelegate.m). At the top of the file, below the line where it says #import "TestAppDelegate.h" add another line that says #import "RootViewController.h"
In the same file there is a method named:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
at the end of the method but before return YES; statement add the following line:
self.window.rootViewController = [[RootViewController alloc] init];
Now go to your RootViewController.m file that you created in the step 2. and at the top of the file edit the interface to have this one instance variable:
#interface RootViewController ()
{
UIView *menuView;
}
#end
In the same file locate the method named - (void)viewDidLoad and add the following code in it: - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor =[UIColor blackColor];
UIButton *menuButton = [UIButton buttonWithType:UIButtonTypeCustom];
menuButton.frame = CGRectMake(100, 60, 50, 50);
[menuButton setBackgroundImage:[UIImage imageNamed:#"menu.png"] forState:UIControlStateNormal];
[menuButton addTarget:self action:#selector(menuButtonTapped:) forControlEvents:UIControlEventTouchDown];
CGRect menuFrame = CGRectMake(20, menuButton.frame.origin.y + 50, 300, 60);
menuView = [[UIView alloc] initWithFrame:menuFrame];
menuView.backgroundColor = [UIColor purpleColor];
menuView.hidden = YES;
UIButton *menuButtonA = [UIButton buttonWithType:UIButtonTypeRoundedRect];
menuButtonA.frame = CGRectMake(5, 5, 50, 50);
[menuButtonA setTitle:#"A" forState:UIControlStateNormal];
[menuView addSubview:menuButtonA];
UIButton *menuButtonB = [UIButton buttonWithType:UIButtonTypeRoundedRect];
menuButtonB.frame = CGRectMake(65, 5, 50, 50);
[menuButtonB setTitle:#"B" forState:UIControlStateNormal];
[menuView addSubview:menuButtonB];
UIButton *menuButtonC = [UIButton buttonWithType:UIButtonTypeRoundedRect];
menuButtonC.frame = CGRectMake(125, 5, 50, 50);
[menuButtonC setTitle:#"C" forState:UIControlStateNormal];
[menuView addSubview:menuButtonC];
UIButton *menuButtonD = [UIButton buttonWithType:UIButtonTypeRoundedRect];
menuButtonD.frame = CGRectMake(185, 5, 50, 50);
[menuButtonD setTitle:#"D" forState:UIControlStateNormal];
[menuView addSubview:menuButtonD];
UIButton *menuButtonE = [UIButton buttonWithType:UIButtonTypeRoundedRect];
menuButtonE.frame = CGRectMake(245, 5, 50, 50);
[menuButtonE setTitle:#"E" forState:UIControlStateNormal];
[menuView addSubview:menuButtonE];
[self.view addSubview:menuButton];
[self.view addSubview:menuView];
}
Below that method add a new method:- (void)menuButtonTapped:(id)sender
{
if (menuView.hidden)
menuView.hidden = NO;
else
menuView.hidden = YES;
}
Find some nice png image on the internet that will represent your menu button. Name it menu.png and drag and drop it in your project(inside the "file" menu on the left side)
That's it run the project ;)
just read the iphone's beginner book. you have to read some book first. first try to understand basic controls in iphone & basic manipulation in objective c
your above work is very basic.now just you are away from one step and that is read a book, you will get lots of free pdf on net

How to insert UIImageView in UITextView in the same way that iphone default message (SMS) app uses to insert multimedia content in the UITextView

I want to insert UIImageView in UITextView of Toolbar having send and camera button in the same way as iPhone default SMS app do.
You would be better off using a UIScrollView and managing UITextViews and UIImageViews in it. UITextView doesn't support adding image inline with text. In fact, it doesn't really support anything other than multiline text.
Per your comment below, there are three things I can think of to get the image as part of the text entry box:
They're not using a UITextView, but instead some custom view. That sort of thing is difficult to replicate.
They are overlaying a UIImageView over the UITextView as a subview and setting the contentInset of the UITextView so there is no overlap.
They are using a separate UIView to contain both the UITextView and UIImageView as subviews and simply arrange those subviews as needed.
Both 2 & 3 are very similar (just slightly different approaches) and probably your best approach. Personally, I think 3 is probably the best, since it give you the most control over the position of both views, but 2 should also work fine.
I agree with Aaron. Based on what I have seen, I believe the native SMS app is actually a UITableView with highly modified TableCells. The TableCells are then composite views that contain the UITextView and UIImageView as Aaron suggested.
It might be a little more work up front, but I think you will find the customization of defining your own UITableCell with the above elements will be quite useful and fall in line with the overall iOS paradigm. Things work a lot better when you work with the native paradigms than against / around them.
Cheers
I have one suggetion that try to make html file with image and text as per your requirements and load that html file into webview.
Here you can also back some particular text Bold etc.
I think nice look then textfield.
To make webview just look like simple scroll view just put this method in your code
don't forgot to write this
webView.opaque = NO;,
[self hideGradientBackground:webView]; and
- (void) hideGradientBackground:(UIView*)theView
{
for (UIView * subview in theView.subviews)
{
subview.backgroundColor = [UIColor clearColor];
if ([subview isKindOfClass:[UIImageView class]])
subview.hidden = YES;
[self hideGradientBackground:subview];
}
}
I hope this may help you.
You can implement it using UITextViewDelegate and ContentInset.
- (void)viewDidLoad
{
self.textView.delegate = self;
[self.textView addSubview:self.addedView];
[self.textView setContentInset:UIEdgeInsetsMake(0, 0, CGRectGetHeight(self.addedView.frame), 0)];
}
- (void)textViewDidChange:(UITextView *)textView
{
NSLog(#"%#",NSStringFromCGSize(textView.contentSize));
__weak typeof(self) wself = self;
[UIView animateWithDuration:0.5f animations:^{
[wself.addedView setFrame:CGRectMake(0, textView.contentSize.height + 10, CGRectGetWidth(wself.addedView.frame), CGRectGetHeight(wself.addedView.frame))];
}];
}

How to repaint a UITextView for iPhone 3.x after updating data programmatically

In my app I update a textView programmatically. I actually loop through a dataset from a SQLITE3 DB and show a specific text for a given time. Then I would like to show the text from the next dataset record and so forth. I have been browsing through all kind of forums and the apple doc as well, but could not find anything like a repaint, refresh, updateTextView or so command.
I am dealing with long strings, why I thought the UITextView would be the best way to display. However, if another UI Class, like the UITextField or UILabel would be better and easier to achieve what I am looking for, I would also use that. No problem.
You can force a UITextField to repaint its text by setting its text color:
textField.textColor = [UIColor colorWithWhite:0.0 alpha:1.0];
The color doesn't need to be different, it simply needs to be a new UIColor instance. The above code will do this. Forcing a repaint can be useful if you have overridden drawTextInRect: and want to change the appearance of the text without changing the text itself.
For performance reasons, calling [textField setNeedsDisplay] will not repaint (or call drawTextInRect:) if the text has not changed.
I was struggling with updating multiline UITextView myself, and I found a solution from the answer of "Phil Calvin"
In my case I used textView.textColor = [UIColor blackColor];
So, here's some more context that may help you in your task...
- (void)textViewDidChange:(UITextView *)textView
{
// ... lots of code to calculate the correct autolayout constraints & content size
[textView setContentSize:CGSizeMake(textFitSize.width, newTextContentHeight)];
[textView.superview setNeedsUpdateConstraints];
[UIView animateWithDuration:0.3
animations:^
{
// first apply the AutoLayout to resize the UITextView
[textView layoutIfNeeded];
[textView.superview layoutIfNeeded];
}
completion:^(BOOL finished)
{
// then update the text by resetting the text colour
dispatch_async(dispatch_get_main_queue(), ^{
[textView.textColor = [UIColor blackColor];
[UIView animateWithDuration:0.3
animations:^(void) {
// do not loose the keyboard
[textView becomeFirstResponder];
}
completion:^(BOOL finished) {
// move the cursor to the bottom of the text view
textView.contentOffset = CGPointMake(0., textView.contentSize.height);
}];
});
}];
}
What exactly is your question?
Are you asking how to set text in a UITextView? Just use its text property:
someTextView.text = #"Some Text";
Are you asking if it's "better" to use a UILabel or UITextField? That's a subjective question. It depends on how your app is designed and what makes the most sense for presenting textual information. (Presenting formatted HTML in a UIWebView is another option.)
Once you set the text of any of these built-in classes, it will know to update/redraw itself. You don't need to set text and then trigger the redrawing or "repainting" manually.
Does [myTextView setNeedsDisplay]; work? That is the traditional way to tell an iOS UIView that it needs to see about redrawing itself. The UIView documentation contains some good information on that.
Ok I got the solution now. As always, it is pretty simple as soon as you know how :-)
As it seems, that I was not very clear on my initial problem description, here the feature description again:
I needed my app to display text from my SQLITE3 database in a UITextView and update that text every 2 seconds with the text from the next record in the DB. So my initial thought was to do it within the Select loop. With the hint of shaggy, that it the view will not be updated, before finishing the loop as it is running in a single thread, I started to look for another solution and came up with the following selector based solution, which works fantastic.
The solution to such a programatic and iterative update of any object in the user interface is a method like this
- (IBAction)displayTextFromArray:(UIButton *)sender{
timer = [NSTimer scheduledTimerWithTimeInterval:(2.0) target:self selector:#selector(displayText) userInfo:nil repeats:YES];
}
This method in my case is invoked when the user touches a UIButton. To make the schedule stop, it is required to send the following message to the timer instance:
[timer invalidate];
Of course I had to change my code a bit to run with the scheduled timer, but from an iteration perspective, the above code is everything you need to trigger and stop a scheduler. Hope that this helps others with a similar issue too.
Cheers, René

Using UISegmentedControl as button

In my code I am using a UISegmentedControl as a "button" with only ONE segment and the momentary property set to YES. In versions of the SDK prior to iOS 4, this was not a problem, but it appears that now iOS 4 requires that there be at least 2 segments. The following code throws an exception:
NSArray *titles = [NSArray arrayWithObject:#"Button Title"];
myButton = [[UISegmentedControl alloc] initWithItems:titles];
and now in Interface Builder you cannot even create a UISegmentedControl with less than 2 segments. It logs the following error when building:
"The number of segments property of a segmented control must be greater than or equal to 2."
I'm kinda stumped. Any work arounds for this? I tried to create a UISegmentedControl with two buttons and then remove one programmatically and that "works" as it doesn't cause the app to crash. I get a button in iOS 3 and nothing in iOS 4. Any ideas?
Have you tried this:
[myButton removeAllSegments];
[myButton insertSegmentWithTitle:#"Press this" atIndex:0 animated:NO];
Really strange. It still works fine for me both in iOS4 simulator and device (this is a real working snippet from my code):
NSArray *laterContent = [NSArray arrayWithObjects: #"Maybe later", nil];
UISegmentedControl *later = [[UISegmentedControl alloc] initWithItems:laterContent];
CGRect frame = CGRectMake( 20,
98,
self.alert.bounds.size.width/2 - 30,
30);
later.frame = frame;
later.selectedSegmentIndex = -1;
[later addTarget:self action:#selector(laterAction:) forControlEvents:UIControlEventValueChanged];
later.segmentedControlStyle = UISegmentedControlStyleBar;
later.tintColor = [UIColor colorWithRed:130.0f/255.0f green:74.0f/255.0f blue:54.0f/255.0f alpha:0.8f];
later.momentary = YES;
later.alpha = 0.9;
It's not exactly a code-related solution but: I hit a similar issue and ended up drawing my own similar looking resources in Photoshop. It was not terribly difficult to do and removed a particular bad "code smell", IMO.
I found if you have a previous project with a single-segment UISegmentedControl, you can open both that project and your new one in Interface Builder and drag (or copy/paste) the single-segment UISegmentedControl to your new view controller. It will work fine in both your app and Interface Builder, just don't change the number of segments from 1 to anything else as it won't let you go back. I'm using Xcode 4.6.2 and iOS 6.
The editor in Interface Builder won't let you change the number of segments to be less than 1, but you can make a segmented control in IB by editing the .xib xml manually.
Right click on the .xib containing the segmented control
Choose Open As -> Source Code from the popup menu.
Find "<segments> which is the beginning of the xml array of segments. The whole thing should look like:
<segments>
<segment title="Segment 1 Title"/>
<segment title="Segment 2 Title"/>
</segments>
Just delete <segment title="Segment 2 Title"/> so there is only one segment element.
Right click the .xib again and choose Open As -> Interface Builder - iOS to go back to interface builder.
You should also probably set the segmented control to "momentary" mode.
I don't get any errors compiling or running this. Of course, this is a hack, and may break things in some circumstances or in a future iOS release.
Well two possibilities:
1) Create a button and the set background image as the single dot of the UISegmentedControl
If your SegmentedControl is a class variable just replace the #property
#property (nonatomic, retain) IBOutlet UIButton *button;
In the viewDidLoad-function add the following
-(void) viewDidLoad
{
[super viewDidLoad];
...
self.button = [UIButton alloc] init];
[self.button setBackgroundImage:[UIImage imageNamed:#"segmentedDot.png"] forState:(UIControlState)UIControlStateNormal];
}
2) Set the amount of segments to three of your UISegmentedControl and afterwards set the width to 20 - now only the dot in the middle will be shown.
Dont forget, if the user interacts with the UISegmentedControl, set the currentElement again to the second segment, else the dot will be in light grey instead of white state.
3) Place a button or a small view over the unwanted second dot of the UISegmentedControl in InterfaceBuilder. Make sure the backgroundcolor is even.
When you are using a button set the state for "user interaction" in attribute inspector to disabled. As type I would chose "custom" since you won't have some borders in your button ;)
Now male again sure, that always the first dot is the active Element.
However I think solution one should be the way you should go, since Apple thought something about it, when they disabled the 1-dot-SegmentedControl. Since you are using the Control as a button the Element you are looking fpr should be a button. ;)
There's no workaround in iOS 4. If you need this functionality, file a bug (enhancement request) at bugreport.apple.com.
You can also use removeSegmentAtIndex:animated:. If you create a segmented control in a storyboard or xib with two segments, you can remove one like this:
[self.sortButton removeSegmentAtIndex:1 animated:NO];

How to parse and show hyperlinks (phone number/email addresses etc) in UILabel?

Almost everywhere in the iPhone, you can type text and the OS will recognize portion of the text to be hyperlinks (phone numbers, email addresses for example). However I tested this in my own app with a UILabel and it doesn't work. How do I activate this?
Does the iphone sdk provide this functionality out of the box or do I have to do the parsing logic myself (which is a lot of work)?
You could use UITextView as follows:
UITextView *myView = [[UITextView alloc] initWithFrame: frame];
myView.text = #"this is http://google.com link";
myView.editable = NO;
myView.dataDetectorTypes = UIDataDetectorTypeLink;
//cell is the TableView's cell
[cell.contentView addSubview:myView];
[myView release];
Might want to check out Styled Labels under the Three20 project.
Give it a shot with a UIWebView.