I have a UITextView in my app. I need to change it's content offset dynamically every time a new string is appended. The code bellow works fine on iOS 6 and earlier versions, but not on iOS 7.
TextViewText.text = [TextViewText.text stringByReplacingCharactersInRange:RecentWordRange withString:string];
newStringLen = string.length;
[TextViewText setSelectedRange: NSMakeRange(RecentWordRange.location+string.length, 0)];
[TextViewText setContentOffset: CGPointMake(0,0) animated:NO];
[TextViewText setContentOffset:contentOffset animated:YES];
what is change in IOS7 for setContentOffset?
Use UITextView's textContainerInset for what would be insets, and use (UIEdgeInsets)contentInset for what would be (CGPoint)contentOffset.
No idea why someone decided this was the best way to handle UITextView offsetting, but this is working for me.
Also note that there is a strange bug that doesn't accept insets on the textView unless there is a right and left offset. So make sure left/right UIEdgeInsets are greater than 1.
Recently I resolved a similar problem in iOS 8. I Replaced text in the text view and it jumped around. Using the UITextRange related method helped.
UITextRange *RecentWordRange = TextViewText.selectedTextRange;
[TextViewText replaceRange:RecentWordRange withText:string];
Related
I have a UITextView with text in it, the View is in a UITableViewCell. I noticed that the font was not quite the same on iOS7 as with iOS6, noting it was set to "system" I decided to specify the exact font/size.
It appeared nothing happened so I thought I would do a better test (big font not used anywhere), like this in my "CellForRowAt....";
cell.newsItemDescription.font = [UIFont fontWithName:#"didot" size:20];
cell.newsItemDescription.text = newsDescriptions[indexPath.row];
In iOS6 it comes out like this;
In iOS7 it comes out like this;
It happens in just a few places in the app but it is very annoying, can't figure out why? I am fast getting to the point where I may use the iOS7 Font/ Size throughout the app.
Some extra info;
The UITextView is resized per cell along with the cell (using springs/struts, i.e. no Auto Layout) and HeightForRow...
The font was setup in Storyboard originally (as system)
This is the same on devices and Simulator
I have a strange behavior in iOS 7. Font is smaller than I expect, if I was set it in to the xib.
If I set font after setting the text it's works for me. Otherwise font is smaller.
Try this:
cell.newsItemDescription.text = newsDescriptions[indexPath.row];
cell.newsItemDescription.font = [UIFont fontWithName:#"didot" size:20];
I had the same issue today with UITextView, and while reading AlKozin's answer, I remembered something: somewhere, sometime I read that since iOS 7, the best practice to set font styles is to set them after the View has loaded. In other words, if I set everything in viewDidLoad: , nothing happens. You have to set up the font of your UITextView in viewWillAppear:, like this:
-(void)viewWillAppear:(BOOL)animated
{
self.myTextView.font = [UIFont fontWithName:#"Baskerville-Italic" size:18.0];
}
I ran into a weird bug (Xcode 7.2.1), where unchecking "Selectable" in IB was causing the UITextView to not adhere to the font settings specified through IB.
This is same issue I was facing.
Making UITextview "selectable" from storyboard will work.
Setting textview.font worked fine for me on iOS 7, but none of these answers, or other similar answers on other SO pages worked for me on iOS 8. The only way I was able to get it working was to use an NSAttributedString.
NSMutableParagraphStyle *pStyle = [[NSMutableParagraphStyle alloc] init];
[pStyle setAlignment:NSTextAlignmentCenter];
tv.attributedText = [[NSAttributedString alloc]
initWithString:text
attributes:#{ NSForegroundColorAttributeName: color,
NSFontAttributeName: [UIFont systemFontOfSize:fontSize],
NSParagraphStyleAttributeName: pStyle,
} ];
The code snippet below worked to resize a UITextView frame to it's content height, before installing Xcode 5 but it doesn't work since the upgrade:
CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;
I've searched and haven't found the fix. Any thoughts?
There's new stuff for this on iOS 7.
To get the "fitted" size used by the text view after it's updated its text, call usedRectForTextContainer: on the textView's layoutManager property, passing the textView's textContainer property as an argument.
Word of warning about scrolling: Be advised, though, that changing the frame size of a text view after it has updated it's text can have unexpected visual bugs if scrolling is disabled on your text view. If this happens, set scrolling enabled before editing the text of the text view, then disabling it after it's updated (if you need scrolling to remain disabled).
To work in iOS 7 (Xcode 5), just:
Give the entire space to receive the text, by setting:
[myTextView setScrollEnabled:YES];
Pass the real text:
myTextView.text = theTextVariable; or myTextView.text = #"The text...";
Autoresize textView:
[myTextView sizeToFit];
Disable scroll:
[myTextView setScrollEnabled:NO];
P.S: myTextView can be use also as self.myTextView or _myTextView
And have fun!
I believe the correct way to force a textView to update its contentSize is by calling
[textView layoutIfNeeded]
However, in iOS 7.0 and 7.1 this seems still not to work reliably unless you first set
textView.layoutManager.allowsNonContiguousLayout = false;
It's not clear to me whether this is a bug or not since I can't really find a good explanation of what "non-contiguous layout" even means.
(My personal use case is updating textView.text = newValue programmatically, then trying to resize the textView appropriately.)
[textView sizeToFit];
Is what you need.
All you need to do is make sure that:
[textView setScrollEnabled:YES];
BEFORE you set the UITextView text content.
You can then:
[textView sizeToFit];
[textView setScrollEnabled:NO];
After you've set the text. Same as writing your own bling function or employing complicated bounding rect methods. Why use something so complicated when the solution is as simple as three lines?
That said, wrap those functions like so:
- (void) setText:(NSString *)theTextToAdd andResizeTheDamnTextView:(UITextView *)textView {
[textView setScrollEnabled:YES];
[textView setText:theTextToAdd];
[textView sizeToFit];
[textView setScrollEnabled:NO];
}
And define it in a per-file or global basis to avoid having to manually write or copy/paste the four lines and call it every time. Just call it as:
[yourTextViewIvar setText:#"DUMMY STRING" andResizeTheDamnTextView:yourTextViewIvar];
If that doesn't work:
[yourTextViewIvar setText:[self setText:#"DUMMY STRING" andResizeTheDamnTextView:yourTextViewIvar]];
And you'll be golden.
I think..
That's Pseudocode. Just FYI.
A easier solution is use that:
[textViewExample sizeToFit];
This work for me.
I use following code to calculate the bound of a UILabel
CGRect bound = [lblName.text boundingRectWithSize:(CGSize){206, 99999}
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
attributes:stringAttributes
context:nil];
The UILabel is a embedded in a UIScrollView, which is a subview of UITableViewCell.
here what i got
I made a test which use a UILabel in a table cell, and a UILabel in UIScrollView separately, and results are as I expected
Note that all setting (font, line break mode etc) of UILabel are the same in all those case. The boundingRectWithSize returns same result in all those case, only difference is the way UILabel render the text.
What is the problem here? did i miss sometthing?
UPDATE: this happen only when i load UILabel from nib, if it is created programmatically, there is no problem. (my project is migrated from xcode 4 to xcode 5)
Try this:
bound.size.height += 1;
UPDATE:
According to Apple's document
- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context
This method returns fractional sizes (in the size component of the returned CGRect); to use a returned size to size views, you must use raise its value to the nearest higher integer using the ceil function.
So you might want to use this approach:
bound.size.height = ceil(bound.size.height);
I was seeing the same behavior with some of my labels, which looked fine in iOS 6, but in iOS 7 they had extra padding at the top and bottom as in your pictures.
Here's what I had to do to finally get it to layout correctly in viewDidLoad - works on both iOS 6 and 7.
self.someLabel.autoresizingMask = UIViewAutoresizingNone;
self.someLabel.frame = CGRectMake(
self.someLabel.frame.origin.x,
self.someLabel.frame.origin.y,
labelWidth, // define elsewhere if you're targeting different screen widths
self.someLabel.bounds.size.height);
[self.someLabel sizeToFit];
My UIDatePicker's background is black (because the background for the whole screen is black probably), but I want white in the background for this UIDatePicker.
Is there any way to change the background color without subclassing it?
iOS 14 update
It looks that datePicker.backgroundColor doesn't work in iOS 14. It works. But you have to put it after preferredDatePickerStyle setting:
let picker = UIDatePicker()
if #available(iOS 13.4, *) {
picker.preferredDatePickerStyle = .wheels
}
picker.backgroundColor = .red
datePickerName.backgroundColor = [UIColor grayColor];
OBJECTIVE C
datePicker.backgroundColor = [UIColor greenColor]
SWIFT
DatePicker.backgroundColor = UIColor.blueColor()
DatePicker.setValue(UIColor.greenColor(), forKeyPath: "textColor")
DatePicker.setValue(0.8, forKeyPath: "alpha")
iOS 14 update
After iOS 14 setting background color this way
datePicker.backgroundColor = <# your bg color #>
doesn't work anymore.
So I'm using key value coding approach now:
datePicker.setValue(<# your bg color #> , forKey: "backgroundColor")
I had this same problem. I just created a UIView and put it behind the UIDatePicker
datePickerBackground = [[UIView alloc] initWithFrame:myDatePickerView.frame];
datePickerBackground.backgroundColor = [UIColor whiteColor];
[self.view insertSubview:datePickerBackground belowSubview:myDatePickerView];
I declared UIView *datePickerBackground; in my class. I reuse this same ViewController so I set datePickerBackground to nil on unLoad.
Simple follow these steps
First you set the delegate in your .h file like:
UIPickerViewDelegate, UIPickerViewDataSource
Then add that line where you created the datepicker
YourDatePicker = [[UIDatePicker alloc] init];
YourDatePicker.backgroundColor=[UIColor whiteColor];
In your case the color is white but you can change it to as you want.
Normally, I would say that UIDatePicker inherits from UIView and that you could set the background programatically via a line like yourDatePickerRef.backgroundColor = [UIColor whiteColor];, but it turns out that -- according to this related question -- UIDatePicker has a number of subviews inside of it, some of which are the backgrounds views.
It's these subviews that you need to set the background color to white (instead of clear or whatever it's currently set to).
Yes, it's a bit of a pain, but this makes UIDatePicker a potentially powerful object in terms of being able to customize the appearance of.
Why not add a plain UIView behind the picker. Set the view's background color to white. Give the view the same frame as the picker.
Note (based on your comment to Michael's answer):
Digging around the private subviews of a UIDatePicker is risky. It could break at any time. It is almost guaranteed that your solution will break for date pickers used on a device with a locale that doesn't use AM/PM since the picker will only have two components instead of three.
I'm trying to create a label programmatically using NSTextField, but it comes out blurry: screenshot
This is my code so far:
NSTextfield *textfield = [[NSTextField alloc] initWithFrame:NSMakeRect(5,5,150,20)];
[texField setStringValue:#"some text here"];
[textField setEditable:NO];
[textField setSelectable:NO];
[textField setBordered:NO]
[textField setDrawsBackground:NO]
I've traced the problem down to the setDrawsBackground line. I've also tried using [textField setBackgroundColor:[NSColor clearColor] as well, but no luck.
By the way, I've adding to a textField to the subview of a view that is a subview of a scrollview. I've also playing with isOpaque on all the view levels, but no luck there again.
Any help is greatly appreciated.
If you have no background (including clear) and your text is a subview of any layer-backed superview (you've turned on "wants layer" in code or in IB to allow animations/transitions), you'll get blurry text. You have to choose either no layer backed view or a label with a solid background color.
I had the same problem, but I have solved it by:
textfield.canDrawSubviewsIntoLayer = true
Make sure you're setting the frame of your NSTextField to something with all integer values.
Use roundf() if necessary.
I was getting a blurry NSTextField, and neither adding a solid background nor removing Core Animation layers from my view hierarchy were options for me. I noticed I was setting the frame of this text field to something with a Y value of 4.5, so the following changes fixed the issue for me:
Blurry label:
_label.frame = NSOffsetRect(_labelFrame,
-0.5 * (someRect.size.width + someConstant),
0.0);
No blur:
_label.frame = NSOffsetRect(_labelFrame,
roundf(-0.5 * (someRect.size.width + someConstant)),
0.0);
(In the above examples, _labelFrame and someRect are NSRects, and someConstant is a CGFloat. As you can see, the calculation I was doing in the second line of the first example was passing a non-integer value to NSOffsetRect).
Since this was my first time subclassing NSView, I had put the above code in the drawRect method instead of the initWithFrame method. I did this because I was following one of the sample applications from Apple's Dev site.
This was also causing my CPU usage to spike when I was scrolling
If you created it via an XIB and it is blurry, I found the fix:
[textField setStringValue:#""];
If I comment this out it goes blurry; if put back it's crystal clear.
Try this below:
textField.drawsBackground = true
textField.backgroundColor = NSColor.white.withAlphaComponent(.leastNormalMagnitude)
Out of the box, but worth to mention. I have wasted by entire day debugging the issue. I am using a non-apple external monitor and this is where the issue is identified. Once i open the app in Mac book pro, it is perfectly fine.
So, the Samsung monitor which i am using might be non-retina.
Simply, add
CanDrawConcurrently = true
property from InterfaceBuilder