So first, I needed to set the placeholder text color, so I subclassed the UITextfield as shown in several stack overflow posts. This works fine. Here is an example post of this: How do I subclass UITextField and override drawPlaceholderInRect to change Placeholder color.
But, when I try to use searchNameField.textAlignment = UITextAlignmentCenter; It is no longer centering the placeholder. The input text is still centered fine.
So then, assuming that the centering is not working because of the subclassing, what do I have to add to my UITextField subclass in order to have the placeholder text centered?
Thanks
Edit
Here is the code I used to solve this problem. This is placed inside my subclass of UITextField.
- (CGRect)placeholderRectForBounds:(CGRect)bounds
{
CGSize size = [[self placeholder] sizeWithFont:[UIFont fontWithName:#"Arial" size:placeholdTextSize]];
return CGRectMake( (bounds.size.width - size.width)/2 , bounds.origin.y , bounds.size.width , bounds.size.height);
}
Note that placeholdTextSize is a property that I set during initialization.
Here you go buddy
subclassing UITextField will do the work:
// CustomTextField.h
#interface CustomTextField : UITextField {
}
#end
override the methods:
#implementation
- (CGRect)placeholderRectForBounds:(CGRect)bounds {
return CGRectMake(x,y,width,height);//Return your desired x,y position and width,height
}
- (void)drawPlaceholderInRect:(CGRect)rect {
//draw place holder.
[[self placeholder] drawInRect:rect withFont:[UIFont systemFontOfSize:12]];
}
#end
i think this will work (tested)
- (void) drawPlaceholderInRect:(CGRect)rect {
[[UIColor redColor] setFill];
[self.placeholder drawInRect:rect
withFont:self.font
lineBreakMode:UILineBreakModeTailTruncation
alignment:self.textAlignment];
}
https://github.com/mschulkind/cordova-true-native-ios/blob/master/Classes/UITextFieldPlugin.m
You can do this in UITextfield subclass
- (void)drawPlaceholderInRect:(CGRect)rect {
[[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.8] setFill];
[[self placeholder] drawInRect:rect withFont:[UIFont boldSystemFontOfSize:16.0] lineBreakMode:UILineBreakModeTailTruncation alignment:NSTextAlignmentCenter];
}
Related
I am creating a custom UISlider and wonder, how do you increase a thumb image's "click area" ? The code below works great, except the thumb's "click area" remains unchanged. If I am not wrong, I believe the standard thumb area is 19 px ? Lets say I would like to increase it to 35px with the following code below, what steps do I need to take? Keep in mind I am not an expert within this area at all.
EDIT The code below is corrected and ready for copy pasta! Hope it helps you!
main.h
#import "MyUISlider.h"
#interface main : MLUIViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UIActionSheetDelegate, UIAlertViewDelegate, MFMailComposeViewControllerDelegate, UIGestureRecognizerDelegate, MLSearchTaskDelegate, MLDeactivateDelegate, MLReceiptDelegate>
{
..........
}
- (void)create_Custom_UISlider;
main.m
- (void)viewDidLoad
{
[self create_Custom_UISlider];
[self.view addSubview: customSlider];
}
- (void)create_Custom_UISlider
{
CGRect frame = CGRectMake(20.0, 320.0, 280, 0.0);
customSlider = [[MyUISlider alloc] initWithFrame:frame];
[customSlider addTarget:self action:#selector(sliderAction:) forControlEvents:UIControlEventValueChanged];
// in case the parent view draws with a custom color or gradient, use a transparent color
customSlider.backgroundColor = [UIColor clearColor];
UIImage *stetchLeftTrack = [[UIImage imageNamed:#"blue_slider08.png"]
stretchableImageWithLeftCapWidth: 10.0 topCapHeight:0.0];
UIImage *stetchRightTrack = [[UIImage imageNamed:#"blue_slider08.png"]
stretchableImageWithLeftCapWidth: 260.0 topCapHeight:0.0];
[customSlider setThumbImage: [UIImage imageNamed:#"slider_button00"] forState:UIControlStateNormal];
[customSlider setMinimumTrackImage:stetchLeftTrack forState:UIControlStateNormal];
[customSlider setMaximumTrackImage:stetchRightTrack forState:UIControlStateNormal];
customSlider.minimumValue = 0.0;
customSlider.maximumValue = 1.0;
customSlider.continuous = NO;
customSlider.value = 0.00;
}
-(void) sliderAction: (UISlider *) sender{
if(sender.value !=1.0){
[sender setValue: 0.00 animated: YES];
}
else{
[sender setValue 0.00 animated: YES];
// add some code here depending on what you want to do!
}
}
EDIT (trying to subclass with the code below)
MyUISlider.h
#import <UIKit/UIKit.h>
#interface MyUISlider : UISlider {
}
#end
MyUISlider.m
#import "MyUISlider.h"
#implementation MyUISlider
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value
{
return CGRectInset ([super thumbRectForBounds:bounds trackRect:rect value:value], 10 , 10);
}
#end
You have to override thumbRectForBounds:trackRect:value: in a custom subclass (instead of calling the method yourself like you do in your code, which does nothing except returning a value that you don't even bother to retrieve).
thumbRectForBounds:trackRect:value: is not a method to set the tumb rect, but to get it. The slider will internally call this thumbRectForBounds:trackRect:value: method to know where to draw the thumb image, so you need to override it — as explained in the documentation — to return the CGRect you want (so that it will be 35x35px as you wish).
Updated for Swift 3.0 and iOS 10
private func generateHandleImage(with color: UIColor) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: self.bounds.size.height + 20, height: self.bounds.size.height + 20)
return UIGraphicsImageRenderer(size: rect.size).image { (imageContext) in
imageContext.cgContext.setFillColor(color.cgColor)
imageContext.cgContext.fill(rect.insetBy(dx: 10, dy: 10))
}
}
Calling:
self.sliderView.setThumbImage(self.generateHandleImage(with: .white), for: .normal)
Original answer:
By far the easiest method is just to increase the size of the thumb image with invisible border around it:
- (UIImage *)generateHandleImageWithColor:(UIColor *)color
{
CGRect rect = CGRectMake(0.0f, 0.0f, self.bounds.size.height + 20.f, self.bounds.size.height + 20.f);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.f);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, CGRectInset(rect, 10.f, 10.f));
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
And than adding this image to slider:
[self.sliderView setThumbImage:[self generateHandleImageWithColor:[UIColor redColor]] forState:UIControlStateNormal];
I also had this problem and solved it by overriding
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
method.
You can return YES for those points, that you want to be touched.
You can check my double slider project
In summary, I implemented the hit test method so the beginTrackingWithTouch is invoked.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if (CGRectContainsPoint(self.leftHandler.frame, point) || CGRectContainsPoint(self.rightHandler.frame, point)) {
return self;
}
return [super hitTest:point withEvent:event];
}
Check the class for further details
why you wanna go for custom slider while you can change the area of a default slider ;)
take a look at this code it worked for me to increase the touch area of my UISlider hope it helps you too
CGRect sliderFrame = yourSlider.frame;
sliderFrame.size.height = 70.0;
[yourSlider setFrame:sliderFrame];
I am creating a custom UISlider and wonder, how do you increase a thumb image's "click area" ? The code below works great, except the thumb's "click area" remains unchanged. If I am not wrong, I believe the standard thumb area is 19 px ? Lets say I would like to increase it to 35px with the following code below, what steps do I need to take? Keep in mind I am not an expert within this area at all.
EDIT The code below is corrected and ready for copy pasta! Hope it helps you!
main.h
#import "MyUISlider.h"
#interface main : MLUIViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UIActionSheetDelegate, UIAlertViewDelegate, MFMailComposeViewControllerDelegate, UIGestureRecognizerDelegate, MLSearchTaskDelegate, MLDeactivateDelegate, MLReceiptDelegate>
{
..........
}
- (void)create_Custom_UISlider;
main.m
- (void)viewDidLoad
{
[self create_Custom_UISlider];
[self.view addSubview: customSlider];
}
- (void)create_Custom_UISlider
{
CGRect frame = CGRectMake(20.0, 320.0, 280, 0.0);
customSlider = [[MyUISlider alloc] initWithFrame:frame];
[customSlider addTarget:self action:#selector(sliderAction:) forControlEvents:UIControlEventValueChanged];
// in case the parent view draws with a custom color or gradient, use a transparent color
customSlider.backgroundColor = [UIColor clearColor];
UIImage *stetchLeftTrack = [[UIImage imageNamed:#"blue_slider08.png"]
stretchableImageWithLeftCapWidth: 10.0 topCapHeight:0.0];
UIImage *stetchRightTrack = [[UIImage imageNamed:#"blue_slider08.png"]
stretchableImageWithLeftCapWidth: 260.0 topCapHeight:0.0];
[customSlider setThumbImage: [UIImage imageNamed:#"slider_button00"] forState:UIControlStateNormal];
[customSlider setMinimumTrackImage:stetchLeftTrack forState:UIControlStateNormal];
[customSlider setMaximumTrackImage:stetchRightTrack forState:UIControlStateNormal];
customSlider.minimumValue = 0.0;
customSlider.maximumValue = 1.0;
customSlider.continuous = NO;
customSlider.value = 0.00;
}
-(void) sliderAction: (UISlider *) sender{
if(sender.value !=1.0){
[sender setValue: 0.00 animated: YES];
}
else{
[sender setValue 0.00 animated: YES];
// add some code here depending on what you want to do!
}
}
EDIT (trying to subclass with the code below)
MyUISlider.h
#import <UIKit/UIKit.h>
#interface MyUISlider : UISlider {
}
#end
MyUISlider.m
#import "MyUISlider.h"
#implementation MyUISlider
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value
{
return CGRectInset ([super thumbRectForBounds:bounds trackRect:rect value:value], 10 , 10);
}
#end
You have to override thumbRectForBounds:trackRect:value: in a custom subclass (instead of calling the method yourself like you do in your code, which does nothing except returning a value that you don't even bother to retrieve).
thumbRectForBounds:trackRect:value: is not a method to set the tumb rect, but to get it. The slider will internally call this thumbRectForBounds:trackRect:value: method to know where to draw the thumb image, so you need to override it — as explained in the documentation — to return the CGRect you want (so that it will be 35x35px as you wish).
Updated for Swift 3.0 and iOS 10
private func generateHandleImage(with color: UIColor) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: self.bounds.size.height + 20, height: self.bounds.size.height + 20)
return UIGraphicsImageRenderer(size: rect.size).image { (imageContext) in
imageContext.cgContext.setFillColor(color.cgColor)
imageContext.cgContext.fill(rect.insetBy(dx: 10, dy: 10))
}
}
Calling:
self.sliderView.setThumbImage(self.generateHandleImage(with: .white), for: .normal)
Original answer:
By far the easiest method is just to increase the size of the thumb image with invisible border around it:
- (UIImage *)generateHandleImageWithColor:(UIColor *)color
{
CGRect rect = CGRectMake(0.0f, 0.0f, self.bounds.size.height + 20.f, self.bounds.size.height + 20.f);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.f);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, CGRectInset(rect, 10.f, 10.f));
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
And than adding this image to slider:
[self.sliderView setThumbImage:[self generateHandleImageWithColor:[UIColor redColor]] forState:UIControlStateNormal];
I also had this problem and solved it by overriding
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
method.
You can return YES for those points, that you want to be touched.
You can check my double slider project
In summary, I implemented the hit test method so the beginTrackingWithTouch is invoked.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if (CGRectContainsPoint(self.leftHandler.frame, point) || CGRectContainsPoint(self.rightHandler.frame, point)) {
return self;
}
return [super hitTest:point withEvent:event];
}
Check the class for further details
why you wanna go for custom slider while you can change the area of a default slider ;)
take a look at this code it worked for me to increase the touch area of my UISlider hope it helps you too
CGRect sliderFrame = yourSlider.frame;
sliderFrame.size.height = 70.0;
[yourSlider setFrame:sliderFrame];
This question already has answers here:
iPhone UITextField - Change placeholder text color
(32 answers)
Closed 9 years ago.
How to to change the color of the placeholder text I set in my UITextField controls, to make it black?
using KVC
[yourtextfield setValue:[UIColor colorWithRed:120.0/255.0 green:116.0/255.0 blue:115.0/255.0 alpha:1.0] forKeyPath:#"_placeholderLabel.textColor"];
you can set your own colour to placeholder
This is a best way to change your placeholder color via KVO...
[txtEmailAddress setValue:[UIColor blackColor] forKeyPath:#"_placeholderLabel.textColor"];
I hope it helps you change placeholder color. Thanks
You can override drawPlaceholderInRect:(CGRect)rect as such to manually render the placeholder text:
- (void) drawPlaceholderInRect:(CGRect)rect {
[[UIColor blueColor] setFill];
[[self placeholder] drawInRect:rect withFont:[UIFont systemFontOfSize:16]];
}
You will have to subclass the UITextField class and override the following method.
- (void) drawPlaceholderInRect:(CGRect)rect
{
[[UIColor blackColor] setFill];
[[self placeholder] drawInRect:rect withFont:[UIFont italicSystemFontOfSize:17] lineBreakMode:UILineBreakModeCharacterWrap alignment:UITextAlignmentLeft];
}
You can use this to change the placeholder text color.
- (void) drawPlaceholderInRect:(CGRect)rect {
[[UIColor blueColor] setFill];
[[self placeholder] drawInRect:rect withFont:[UIFont systemFontOfSize:16]];
}
Make use of the following code. which will help you.
- (void) drawPlaceholderInRect:(CGRect)rect
{
[[UIColor redColor] setFill];
[[self placeholder] drawInRect:rect withFont:[UIFont systemFontOfSize:16]];
}
I have created Custom UITextView class ,where textView grows dynamically as user types characters and textview frame resized dynamically.I want to align the text vertically center in the frame,it always coming to bottom by default.I added UIEdgeInsets to make or look a like it into center but it creates more issues for me.If i try to set content offset then the textView center also shifts.Is the content offset and textView center effect each other ?.I want textview center where ever it is but the text inside the textView stays vertically center.
Initially i am setting UITextView font 23.0 with a rectangular border(textview frame layer border).When i start typing in that box the text is coming on bottom of the border.Then i am using
[textView setContentInset:UIEdgeInsetsMake(5,0,10,0)];
to make text in center. Then i have to send this text for printing which is placed on an UIImageView.Here i am using the mentioned code by Paras to match printer dpi and resizing it.But the text as looks on UIImageview doesn't match the exact placement of print because i have added UIEdgeInset to adjust vertical alignment
I have two types to set dynamic height to the UITextView see both are bellow...
UPDATE:
First Create UITextView programmatically like bellow...
-(IBAction)btnAddTextView:(id)sender
{
UIView *viewTxt = [[UIView alloc]initWithFrame:CGRectMake(imgBackBoard.center.x - 100,20, 220, 84)];
[viewTxt setBackgroundColor:[UIColor clearColor]];
viewTxt.userInteractionEnabled = YES;
UITextView *txtAddNote=[[UITextView alloc]initWithFrame:CGRectMake(20,20, 180, 44)];
[txtAddNote setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor]];
[txtAddNote setFont:[UIFont fontWithName:#"Helvetica-Bold" size:15]];
txtAddNote.layer.borderWidth = 2.0;
txtAddNote.layer.borderColor= [UIColor redColor].CGColor;
viewTxt.tag = 111;
txtAddNote.tag = 111;
txtAddNote.userInteractionEnabled= YES;
txtAddNote.delegate = self;
txtAddNote.textColor = [UIColor whiteColor];
[viewTxt addSubview:txtAddNote];
[viewBoard addSubview:viewTxt];
[txtAddNote release];
}
First
1. This bellow Method is Delegate Method of UITextViewDelegate.
in .h class add this UITextViewDelegate and then give your textView.delegate to self like bellow..
yourTextView.delegate = self;
and use paste this bellow method...
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
textView.frame = CGRectMake(textView.frame.origin.x, textView.frame.origin.y, textView.frame.size.width, textView.contentSize.height);
return YES;
}
here when your UITextView editing at a time with its text, the content size of textView is change.
2. Use my bellow custom Method for set Dynamic Height of UILable,UITextField and also UITextView
-(float) calculateHeightOfTextFromWidth:(NSString*) text: (UIFont*)withFont: (float)width :(UILineBreakMode)lineBreakMode
{
[text retain];
[withFont retain];
CGSize suggestedSize = [text sizeWithFont:withFont constrainedToSize:CGSizeMake(width, FLT_MAX) lineBreakMode:lineBreakMode];
[text release];
[withFont release];
return suggestedSize.height;
}
use this method like bellow...
CGSize sizeToMakeLabel = [yourTextView.text sizeWithFont:yourTextView.font];
yourTextView.frame = CGRectMake(yourTextView.frame.origin.x, yourTextView.frame.origin.y,
sizeToMakeLabel.width, sizeToMakeLabel.height);
I would like to write a UIView subclass that, among other things, colors whatever's underneath it a certain color. This is what I've come up with, but it unfortunately doesn't seem to work correctly:
#import <UIKit/UIKit.h>
#class MyOtherView;
#interface MyView : UIView
{
MyOtherView *subview;
}
#end
#implementation MyView
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
frame.origin.x += 100.0;
frame.origin.y += 100.0;
frame.size.width = frame.size.height = 200.0;
subview = [[MyOtherView alloc] initWithFrame:frame];
[self addSubview:subview];
[subview release];
}
return self;
}
- (void)drawRect:(CGRect)rect
{
// Draw a background to test out on
UIImage *image = [UIImage imageNamed:#"somepic.png"];
[image drawAtPoint:rect.origin];
const CGContextRef ctx = UIGraphicsGetCurrentContext();
[[UIColor blueColor] setFill];
rect.size.width = rect.size.height = 200.0;
CGContextFillRect(ctx, rect);
}
#end
#interface MyOtherView : UIView
#end
#implementation MyOtherView
- (void)drawRect:(CGRect)rect
{
// This should tint "MyView" but it doesn't.
const CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
CGContextSetBlendMode(ctx, kCGBlendModeScreen);
[[UIColor redColor] setFill];
CGContextFillRect(ctx, rect);
CGContextRestoreGState(ctx);
}
#end
I want "MyOtherView" to color "MyView" red where it overlaps, but instead it just draws an opaque red block onto it. However, this seems work fine if I copy the -drawRect: function from "MyOtherView" and append it to the one in "MyView" (this took me quite a headache to finally realize). Anyone know what I'm doing wrong? Is it even possible to do this, or should I be approaching it differently?
I think you're over-thinking this. Overlay one view over the other, and set the alpha of the top view to 0.5. You will also need to set opaque to NO.
If you set the background color of the view appropriately, you won't even need to override drawRect.
Might want to check out this SO question.