Earlier today I was trying to get some text in my app to autoscroll through the lyrics of the song that was currently playing and I got an answer to use the animateWithDuration method to get the scroll to work properly. It worked fantastically until I noticed that when I use the following code, something covers up 80% of the textView in the same color as the textView background. When I swipe on the area covered (both in the simulator and on my test devices), the box (or whatever it is) disappears and all the text appears as normal. I know it's the method call of animateWithDuration, because I commented it out and the text isn't covered when I build and run with it not included in the project. Also I went into Interface Builder and changed the color of the textView to white (it was black along with the backgrounds of everything else in the view) to see if what was covering it had a black background as well. When I changed it to white, the text was still covered, this time by a white box. Again it's only the very first time I unhide the textView and populate it with the lyrics for the song. After I swipe across the covered area, any song I play the obstruction doesn't appear. Just the initial time until it's swiped away. Here is the code I'm using...
// set the textView to start at the top of the document
[textView setContentOffset:CGPointZero];
CGPoint scrollPoint = textView.contentOffset;
// set the scroll point to the length of the text view, so it knows how far down to go
scrollPoint.y= [textView.text length];
The following is what causes the text to get covered
`// animate down to that point at the rate of the length of the song minus 20 seconds (so the lyrics can catch up to the song)
[UIView animateWithDuration:(self.myMusicPlayer.duration - 20)
delay:0
options:UIViewAnimationOptionAllowUserInteraction
animations:^(void) {self.textView.contentOffset = scrollPoint;}
completion:nil];`
And here's a photo of the before and after swiping the boxed area.
Anyone have any idea what is covering the text or what I can do to get rid of it? Or another way I could autoscroll through the lyrics using another method besides animateWithDuration?
Here is the code I'm using to populate the textView with the lyrics.
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { // determine which row was clicked
NSUInteger row = [indexPath row];
// get the song name from the array at the position clicked
NSString *rowString = [songNames objectAtIndex:row];
// load the lyrics for the song played into the textView
// load the text file for the song selected
NSString *lyrics = [[NSBundle mainBundle] pathForResource:rowString ofType:#"txt"];
NSString *fileContents = [NSString stringWithContentsOfFile:lyrics];
// set the textView to load the lyric sheet for the song selected
self.textView.text = fileContents; // more after this, but this is all that I'm doing with the textView
EDIT: Well, I've solved the issue of the black box covering the text, though I don't understand it. While I was formatting the text file to flow better with the lyrics, my carriage returns as well as breaking lines up cause the text to get covered. I deleted the contents of the text file and re-pasted the original, resulting in none of the text being covered up. So now I guess my quest is to figure out how to format the text in the text file without having the text covered up. Any suggestions?
So apparently the text document was stored somewhere within the app, as I deleted all the text files in the resources folder and the text for the lyrics still appeared. I'm guessing it was using the size of the text files that were stored as anytime I made the text file smaller (by deleting lines from the double spacing), is where the problem came in. I formatted it how I wanted, and added a bunch of carriage returns at the end of my text document, and it works fine now.
Related
I can't test this code in the iphone simulator but I was wondering if this is the best way to add a caption to a photo someone has taken in the UIImagepickercontroller class.
- (void)imagePickerController:(UIImagePickerController *) Picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
_selectedImage.image = [info objectForKey:UIImagePickerControllerOriginalImage];
UITextField *caption= [[UITextField alloc] initWithFrame:CGRectMake( 60,640,200,40)];
caption.borderStyle = UITextBorderStyleRoundedRect;
caption.font = [UIFont systemFontOfSize:15];
caption.placeholder = #"Type Caption";
[caption release];
}
This is the flow I would take
Let user select / take a picture
Once user hits ok show a prompt to let them enter text.
Sample Project 1
Sample Projects 2
Create a UIImageView and add their selected picture to it
Create a UILabel and add it on top of the UIImageView
Add their text to UILabel.
If you need to save the image with text on top of it then you need some sort of custom photo editor code or just take a screenshot and save it.
The code you posted does not make much sense for what you are trying to do, since it does not look like you are actually linking the caption to the image in any way. I also do not know why you are releasing the text field - unless you turned Automatic Reference Counting off, that code should return an error.
What I would do (and did, to an extent, in a project of mine) is the following:
(1) Create some sort of object, like UserImg, which has two properties of type UIImage and NSString respectively.
(2) In the above function, when an image is selected, create a new UserImg and set the UIImage property to the select image.
(3) Display an UIAlertView with a text box and an okay and cancel button. Use the text box to get the caption you want the user to save with the image.
(4) Set up a function to listen to the UIAlertView for okay and cancel button presses. If the user cancels, remove the new UserImg. If the user hits okay, copy the input text to the UserImg's NSString property.
(5) Profit? I am not sure of the context of the image taking, so you'll have to figure out how you want to display things yourself.
You can test this functionality on the simulator as well. You just need to set the code up so that it picks images from the device's image folder if no camera is present. I forget exactly how to do this and do not currently have my source code on me. I'll edit the answer later to include that if you cannot figure it out yourself in that time.
You will also have to add images to the simulator to choose from. To do that, exit out of any apps running on the simulator (hit the home button, like you would on an actual device) and drag an image over on top of it. When you do, in the top right corner, there should be an option to save the image to the device.
EDIT:
I noticed the comment you added about putting the caption below the image. To do that, I would create a UserImgView which consisted of a UIImageView and a UILabel. That way, when displaying the image using the custom view, you can display the UIImage in its ImageView and the caption right below it in the label.
Best way would be to create a NSDictionary
NSMutableDictionary *photoCaptionDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:_selected.image,#"image",caption.text,#"caption",nil];
Whenever you want to show the picture you just do
[photoCaptionDict objectForKey:#"image"];
and
[photoCaptionDict objectForKey:#"caption"];
shows the text.
I have an UISLider created programmatically inside UITableViewCell. the slider control works with audio file to show the progress .. this is the creation:
AudioSlider = [[UISlider alloc] initWithFrame:CGRectMake(78.0f, 28, 214, 10)];
AudioSlider.maximumValue = 100.0;
AudioSlider.minimumValue = 0.0;
[AudioSlider setTag:5];
[AudioSlider setValue:0.0];
[[self contentView] addSubview:AudioSlider];
the problem is that the slider does not show the start and end values of the progress correctly !! when I set value to 0.0 :
[AudioSlider setValue:0.0];
[AudioSlider setValue:100.0];
the photo explain the problem
I can't really find out the reason ...
Any idea ?
thanks in advance ..
You have omitted some important code from your question. It is clear from your screen shot that you have made the slider's thumb invisible, perhaps by using a transparent image.
Normally, the slider would cover those ends, so the user wouldn't see the wrongly-colored parts of the channel. But by making the thumb invisible, you've made the ends visible.
If this is really supposed to be a slider that the user can interact with, you need to replace the minimum track image and maximum track image of the slider, or you need to use a thumb image that hides the ends.
If this isn't supposed to be a control that the user can interact with, use UIProgressView instead of UISlider.
It's in a tableView so I'd suggest that you're probably not setting it when you think you are due to cell dequeueing.
Can you show the code that creates and configures the UITableViewCells.
I'm wanting to create a read only text area in my app which allows the user to click on any word and the app reads it out. I am however a little confused on which method would be the best. I see two options, use a UILabel and create some method to detect the region clicked then match it to the word in that region but it sounds hard to implement. On the other hand I could use an array of words to create a list of UIbutton's. Any advice and/or sample code to help me would be much appreciated, thanks Jason.
Note: Each view has about 30 words on it.
The solution below works well. For anyone else wanting to use this, these four lines will set your UIWebView to have a clear background and disable any scrolling or bounce.
[[myWebView.subviews objectAtIndex:0] setScrollEnabled:NO];
[[myWebView.subviews objectAtIndex:0] setBounces:NO];
[myWebView setBackgroundColor:[UIColor clearColor]];
[myWebView setOpaque:NO];
And some handy css to stop the open popup when a user presses and holds a link.
*{-webkit-touch-callout:none; -webkit-user-select: none;}
How big is your text area? If it's big then creating a UIButton for each work sounds like sa bit of effor to get the text to layout correctly.
I would use a UIWebView - make each word like this :
WORD1 WORD2 WORD3
and attach your view controller as the webView's UIWebViewDelegate delegate.
Then, you can intercept presses on each word using the webView:shouldStartLoadWithRequest:navigationType: delegate method :)
does anyone know of a way I can change the text label for on and off to yes and no.
I did it with
((UILabel *)[[[[[[switchControl subviews] lastObject] subviews] objectAtIndex:2] subviews] objectAtIndex:0]).text = #"Yes";
((UILabel *)[[[[[[switchControl subviews] lastObject] subviews] objectAtIndex:2] subviews] objectAtIndex:1]).text = #"No";
However, with the release of iOS 4.2, this is no longer supported (this probably wasn't recommended by Apple anyway)
My client is insisting on yes/no switches. I'd appreciate any advice!
many thanks
Hurrah! From iOS 6, it's possible to specify an image to be used for the on / off states, respectively. So, this can be used to display a YES / NO image (or whatever image representing the text you would prefer to use instead of the previously limited ON / OFF).
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"6.0"))
{
[mySwitch setOnImage: [UIImage imageNamed:#"UISwitch-Yes"]];
[mySwitch setOffImage:[UIImage imageNamed:#"UISwitch-No"]];
}
The images should be 77 px wide, 27 px high, and the text (one image for each state) should be horizontally centred within that 77 px width. I use transparent backgrounds for the text, so I can still make use of the tint for the background, which still works with this.
Of course, it would seem easier to just supply text, rather than having to use an image of text, but I'm certainly grateful for this new option, at least.
You need to implement your custom UISwitch for that. Or use one of already implemented :) (check this SO question and this post)
Vladimir answer is great, but in my humble opinion there is an even better implementation here: https://github.com/domesticcatsoftware/DCRoundSwitch.
Besides setting a custom text, it is easier to change the size and color of the UISwitch and you get a sharper result.
It is released under an MIT license. Have a look!
It turns out that you can create a custom UISwitch with the following items:
A UIScrollView
A UIButton
Two UILabels
A background image
A Boolean value
First you will need to add QuartzCore.framework to your project and #import <QuartzCore/QuartzCore.h> to your view controller.
Next add the UIScrollView to your view using Interface Builder. The ScrollView will be your custom UISwitch.
Next add the button and the two labels to your ScrollView. One label will be for "yes" the other for "no".
Add the image to the button and set its type to custom. This is the image I use:
Position the labels over the blue and white area of the image. Adjust the ScrollView so it is just big enough to show the blue part of the image and the thumb nob.
Add the following line to viewDidLoad:
self.mySwitch.layer.cornerRadius = 13.5;
mySwitch is the name of the ScrollView and 13.5 is half the height of the ScrollView. The above statement changes the ScrollView to have rounded ends like the UISwitch.
To make the custom switch active you will need to tie the buttons "Touch Up Inside" event to an IBAction. Here is the code I use in the event handler:
-(IBAction)mySwitchButton:(id)sender {
self.myValue = !self.myValue;
CGPoint scrollPoint = CGPointMake((self.myValue)? 43.0: 0, 0.0);
[mySwitch setContentOffset:scrollPoint animated:YES];
}
Where myValue is the boolean variable that contains the state of your switch and 43.0 is the number of points you will have to move the image over to put the switch in the off position.
That is all there is to it!
From iOS 6, it's possible to specify an image to be used for the UISwitch on / off states, but NOT the text.
This will lead trouble when internationalization is required because translators
have to provide an image text for each language, not text only.
Moreover, the size of the UISwitch image is fixed, limiting the text length.
Because of the above reasons, I like the JSWilson's answer: simple and flexible.
To relieve developers of the need to manually add the required controls, I coded a custom CRDScrollSwitch class that you can find at my GitHub repository:
https://github.com/corerd/CRDScrollSwitch
I am getting an interesting warning at build time (iPhone simulator) that gives the following:
EditView.xib:35:0 UITextView does not support data detectors when the text view is editable.
This is basically non existent on google and I would like to remove it.
My editview.xib has a textview where I write notes into it. Is there any more info that is needed?
I have four different Xibs with similar TextViews that are used for notes as well. I was getting the same warnings. The suggestion to disable the "Detects Phone Numbers" and "Detects Links" does removes the warnings. However, I wanted my users to still have the ability to use the detectors in my notes.
This is how I solved the issue in my app:
In IB: I deselected the two properties for the TextView. -(which does stop the build warnings).
In my - (void)viewDidLoad { I set the properties of the textView to the following:
myTextView.dataDetectorTypes = UIDataDetectorTypeAll; which enables the data detectors of all types (phone numbers and url addresses).
In my View Controller's: -(void)textViewDidBeginEditing:(UITextView *)sender {
method, I turned the data detectors back OFF using: myTextView.dataDetectorTypes = UIDataDetectorTypeNone
Then taking advantage of the -(void)textViewDidEndEditing:(UITextView *)sender {
method, I turned them back ON using: myTextView.dataDetectorTypes = UIDataDetectorTypeAll;
This method disables the data detectors when the user is editing the UITextView and turns the data detectors back ON when the user is finished editing. This Fix allowed for selection of the phone numbers and URL from within the textView, so that I did not loose the function.
I found the following in the Apple Docs on the DataDetectors for UITextView: after playing around with the UITextView for a while, hope it helps.
UIDataDetectorTypes:
Defines the types of information that can be detected in text-based content.
Types:
UIDataDetectorTypePhoneNumber;
UIDataDetectorTypeLink;
UIDataDetectorTypeNone;
UIDataDetectorTypeAll;
Update: 11-5-2010;
Extra Note:
Data detectors are not permitted if UITextView is "Editable", because there would be too many variables to track users changes to text as well as touches with trying to execute phone call or links.
Solution:
Load the TextView with self.textView.editable = NO; and set you UIDataDetector's based on the types I listed above. This way if the user wants to "select" web address or phone number etc, the delegate can handle. When you need your user to edit the textView, then turn ON the self.textView.editing = YES; & remove your UIDataDetectors accordingly. This should assure no errors or warnings during compiling.
Special Consideration:
Be sure to first remove the datadectors when re-enabling, then enable "editing = YES;"...The order is important no to enable editing if UIdatadetectors are still assigned.
Therefore, the sequence order should be something like this...
To Edit textView: 1. remove data detectors, 2. then enable editing = YES.
To Use DataDetectors: 1. Disable Editing = NO; 2. then add data detectors.
I was seeing this warning as well. Here's how I fixed it:
In the xib file in Interface Builder, select your text view, and bring up the attributes inspector. Make sure that "Detects Phone numbers" and "Detects Links" are both UNCHECKED.
I had "Detects Links" checked, and turns out that's what was causing the warning. Basically, if the textview is editable, you don't want these auto-detect features turned on.
So Wordy!
textView.editable = NO;
textView.dataDetectorTypes = UIDataDetectorTypeAll;
the URL address must start with "http://", otherwise the textview cannot detect it.
I thought about trying to use a Tap-Gesture-Recognizer with "delaysTouchesBegan = YES" and "cancelsTouchesInView = NO"
It is still quite easy to solve!
Load view with editable disabled as well as UIDataDetectorTypeAll or the types of links you want to detect. Then add a GestureRecognizer:
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(editTextRecognizerTabbed:)];
recognizer.delegate = self;
recognizer.numberOfTapsRequired = 1;
[self.textViewNotes addGestureRecognizer:recognizer];
So you can change settings within this method:
- (void) editTextRecognizerTabbed:(UITapGestureRecognizer *) aRecognizer;
{
self.textViewNotes.dataDetectorTypes = UIDataDetectorTypeNone;
self.textViewNotes.editable = YES;
[self.textViewNotes becomeFirstResponder];
}
And at least you have to change the edit and detections settings back after user has finished the text input:
- (void)textViewDidEndEditing:(UITextView *)textView;
{
self.textViewNotes.editable = YES;
self.textViewNotes.dataDetectorTypes = UIDataDetectorTypeAll;
}
works lika a charm!
Data detectors for the UITextView would be for copy and paste. Since you are setting it as editable, copy/paste shouldn't be allowed where you think paste should, but copy shouldn't.
Simplenote somehow does this on iOS 4. (There's a free/lite version in case you wanna try.)
It acts a little bit different:
When tapping on one of the highlighted parts, it still starts the editing, and won't follow the link.
But when you tap-and-hold on a detected dataTpye, it shows yout the menu for calling, open the link or whatever.
Also, when tapping inside the text the editing really starts at the place you tapped.
So they somehow remove the dataDectectors, enable editing AND get the touches forwarded to the editable UITextview AFTER the tap is recognized.
Any ideas how to do that?
I thought about trying to use a Tap-Gesture-Recognizer with "delaysTouchesBegan = YES" and "cancelsTouchesInView = NO"
So I can remove the dataConnectorTypes and set it editable on the action method of the recognizer,
and hopefully the touches to the UITextview are delivered AFTER that.
But haven't had time to test it so far.