Ok, I have done this kind of thing a million times but this particular case escapes me and I'm sure its just something stupid I am missing...
But I am trying to display a UIView on top of a mapView to give the impression the mapview is 'disabled.'
I created a UIView subclass and added a single label. like so...
.h
#import <UIKit/UIKit.h>
#interface DisabledOverlayView : UIView
#property (nonatomic, strong) UILabel *disabledOverlayViewText;
#end
nothing complicated...
in my .m I set the text and add it to my UIView.
#synthesize disabledOverlayViewText = _disabledOverlayViewText;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor blackColor];
self.alpha = 1;
_disabledOverlayViewText.textColor = [UIColor whiteColor];
_disabledOverlayViewText.frame = CGRectMake(0, 0, 200, 200);
// [_disabledOverlayViewText setCenter:self.center];
_disabledOverlayViewText.text = #"testing";
[self addSubview:_disabledOverlayViewText];
}
return self;
}
then the class i wish to use this overlay i call it with...
DisabledOverlayView *disabledView = [[DisabledOverlayView alloc] initWithFrame:CGRectMake(12, 12, _mapView.frame.size.width, _mapView.frame.size.height)];
disabledView.disabledOverlayViewText.text = #"No Location";
[self.view addSubview:disabledView];
None of this is too complicated.. but the label doesn't show up. the overlay appears just fine, but no label text. Ive messed with the frames of the label thinking maybe it was off the visible view but no dice. and i cannot figure out what is going on.
Replace your initWithFrame method with the below code. I have added the alloc init line and changes the background color of the label. Try it and see whether it works :)
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor blackColor];
self.alpha = 1;
_disabledOverlayViewText = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
_disabledOverlayViewText.textColor = [UIColor whiteColor];
_disabledOverlayViewText.backgroundColor = [UIColor blackColor];
// [_disabledOverlayViewText setCenter:self.center];
_disabledOverlayViewText.text = #"testing";
[self.view addSubview:_disabledOverlayViewText];
}
It seems the label is not allocated and it's nil.
Try this
(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor blackColor];
self.alpha = 1;
self.disabledOverlayViewText = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
_disabledOverlayViewText.textColor = [UIColor whiteColor];
// [_disabledOverlayViewText setCenter:self.center];
_disabledOverlayViewText.text = #"testing";
[self addSubview:_disabledOverlayViewText];
}
Related
I have a UIView that contains drop shadows and corners which I am loading four of in my UIViewController and I am seeing a performance hit when the screen loads. Since I am using the same white background with shadows and corner radii I figured I would store the UIView in NSCache.
When I run the app there is a large gap where the first UIView should be, however, it is not showing up. What does show up is the last view in my list of views. If I comment out the last one and run it again, the third one shows up. It seems like I am having an issue with the pointer in memory but not sure. Perhaps I am using NSCache incorrectly?
(Note: The first view shown is not using the NSCache)
Here is how I am using the NSCache:
.h file
#interface LunchDetailViewController : UIViewController <UIScrollViewDelegate>
#property (nonatomic) IBOutlet UIScrollView *scrollView;
#property (nonatomic, strong) NSCache *entreeViewsCache;
#end
.m file
#synthesize scrollView;
#synthesize entreeViewsCache;
- (void)viewDidLoad
{
[super viewDidLoad];
self.entreeViewsCache = [[NSCache alloc] init];
UIView *entreeView = [[UIView alloc] init];
entreeView.backgroundColor = [UIColor whiteColor];
entreeView.layer.masksToBounds = NO;
entreeView.layer.cornerRadius = 3.0;
entreeView.layer.shadowOffset = CGSizeMake(1.1, 2.1);
entreeView.layer.shadowOpacity = 0.2;
[self.entreeViewsCache setObject:entreeView forKey:#"EntreeView"];
}
- (void) configureScrollView
{
// This line of code allows the scroll view to be 'scrollable'.
self.scrollView.contentSize = CGSizeMake(320, 620);
UIView *elementaryRoundedCornerView = [self.entreeViewsCache objectForKey:#"EntreeView"];
elementaryRoundedCornerView.frame = CGRectMake(15,15,290,180);
UIView *middleRoundedCornerView = [self.entreeViewsCache objectForKey:#"EntreeView"];
middleRoundedCornerView.frame = CGRectMake(15,210,290,180);
UIView *highRoundedCornerView = [self.entreeViewsCache objectForKey:#"EntreeView"];
highRoundedCornerView.frame = CGRectMake(15,404,290,180);
NSMutableArray *entreeItems = [[NSMutableArray alloc] initWithObjects:#"Pancakes w/ Sausage Patties", #"Corn Dog", #"Grilled Cheese Sandwhich", #"Chicken Tender Wraps", nil];
UIView *elementaryLunchMenuDetails = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 240, 160)];
[elementaryLunchMenuDetails addSubview:[self returnNativeCode:entreeItems rectDimensions:CGRectMake(2, 5, 215, 160) schoolType:#"Elementary"]];
[elementaryRoundedCornerView addSubview:elementaryLunchMenuDetails];
UIView *middleLunchMenuDetails = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 240, 160)];
[middleLunchMenuDetails addSubview:[self returnNativeCode:entreeItems rectDimensions:CGRectMake(2, 2, 215, 160) schoolType:#"Middle"]];
[middleRoundedCornerView addSubview:middleLunchMenuDetails];
UIView *highLunchMenuDetails = [[UIView alloc] initWithFrame:CGRectMake(10,10, 240, 160)];
[highLunchMenuDetails addSubview:[self returnNativeCode:entreeItems rectDimensions:CGRectMake(2, 2, 215, 160) schoolType:#"High"]];
[highRoundedCornerView addSubview:highLunchMenuDetails];
[self.scrollView addSubview:elementaryRoundedCornerView];
[self.scrollView addSubview:middleRoundedCornerView];
[self.scrollView addSubview:highRoundedCornerView];
}
Wow. That's clever. But not correct.
Instead of using NSCache to duplicate a view, you probably want to create a UIView subclass that formats the view the way you want. Then just throw a bunch of those views on your scrollview.
ABCView.m
#implementation ABCDayView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor whiteColor];
self.layer.masksToBounds = NO;
self.layer.cornerRadius = 3.0;
self.layer.shadowOffset = CGSizeMake(1.1f, 2.1f);
self.layer.shadowOpacity = 0.2f;
}
return self;
}
- (void)setItems:(NSArray *)items
{
if ([_items isEqualToArray:items] == NO) {
_items = items;
[self createItemViews];
[self setNeedsLayout];
}
}
// You'll also need to add -createItemViews and -setNeedsLayout methods.
.m file
- (void)configureScrollView
{
NSMutableArray *entreeItems = #[#"Pancakes w/Sausage Patties",
#"Corn Dog",
#"Grilled Cheese Sandwhich",
#"Chicken Tender Wraps"];
CGRect frame = CGRectMake(15,15,290,180);
ABCDayView *elementaryView = [[ABCDayView alloc] initWithFrame:frame];
elementaryView.items = entreeItems;
CGFloat y = CGRectGetMaxY(elementaryView.frame) + 10.0f;
frame = CGRectMake(15, y, 290, 180);
ABCDayView *middleView = [[ABCDayView alloc] initWithFrame:frame];
middleView.items = entreeItems;
...
CGFloat length = // Use CGRectGetMaxY on the last frame to get the length.
self.scrollView.contentSize = CGSizeMake(320, length);
}
That's by no means perfect code. But hopefully it will give you an idea of a better way to implement this.
I am trying to add border around UITextView by using
self.textView.layer.borderWidth = 1;
self.textView.layer.borderColor = [[UIColor brownColor] CGColor];
but it is not showing up. If anyone can help me with why it is not showing up. Eventhough i have added Quartz framework. But still is not showing up.
#import "uitextviewViewController.h"
#import <QuartzCore/QuartzCore.h>
#implementation uitextviewViewController
#synthesize textView;
#synthesize navBar;
- (void)dealloc {
[navBar release];
[textView release];
[super dealloc];
}
- (void) viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem * button = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(done:)];
[[self navigationItem] setRightBarButtonItem:button];
[button release];
self.textView = [[[UITextView alloc] initWithFrame:self.view.frame] autorelease];
self.textView.textColor = [UIColor whiteColor];
self.textView.font = [UIFont fontWithName:#"Arial" size:15];
self.textView.delegate = self;
self.textView.backgroundColor = [UIColor brownColor];
self.textView.layer.borderWidth = 1;
self.textView.layer.borderColor = [[UIColor brownColor] CGColor];
self.textView.textAlignment = UITextAlignmentCenter;
self.textView.text = #"This is UITextView\n\nThis is UITextView\n\nThis is UITextView\n\nThis is UITextView\n\nThis is UITextView.";
self.textView.scrollEnabled = YES;
[self.view addSubview: self.textView];
}
I will appreciate help.
Thanks in advance.
Following code is use for the give the arc of the UITextbox or other controller for that you need to use the #import frame work then you can use the following code for the border or arc shape on the control.
imgThumb.layer.cornerRadius = 5;
imgThumb.layer.masksToBounds = YES;
imgThumb.layer.borderColor = [UIColor grayColor].CGColor;
imgThumb.layer.borderWidth = 0.9;
If any query regarding this please comment here...
Happy coding
Here, use this.
Modify it as you'd like.
UITextFieldWrapper.h
#import <UIKit/UIKit.h>
#interface UITextFieldWrapper : UIView
#property (nonatomic, weak, readonly) UITextField * textField;
#end
UITextFieldWrapper.m
#import "UITextFieldWrapper.h"
#import <QuartzCore/QuartzCore.h>
#implementation UITextFieldWrapper
#synthesize textField = _textField;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.layer.borderWidth = 1.0;
self.layer.borderColor = [[UIColor blackColor] CGColor];
self.backgroundColor = [UIColor whiteColor];
self.clipsToBounds = YES;
UITextField * textField = [[UITextField alloc] initWithFrame:CGRectMake(3, 3, frame.size.width - 6, 21)];
textField.backgroundColor = [UIColor whiteColor];
[self addSubview:textField];
_textField = textField;
}
return self;
}
#end
i have created a custom view class which is a subclass of UIview class
#interface CustomViewController : UIView
and i am using drawRect method to display the contents of the custom view
-(void) drawRect(CGRect) rect {
}
I am able to display only strings on custom view but i want to add UITextField and UILabelField and UIButton on the custom view how can i do this. Please help me solve this problem
you can put your controls in init... method of your custom view.
EDIT
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
messageLabel.frame = CGRectMake(10, 20, innerView.frame.size.width-20, 100);
messageLabel = [messageLabel getSize:messageText FontName:#"Helvetica" FontSize:16 label:messageLabel];
messageLabel.textColor = [UIColor blackColor];
messageLabel.textAlignment = UITextAlignmentCenter;
messageLabel.backgroundColor = [UIColor clearColor];
messageLabel.frame = CGRectMake(10, 40, innerView.frame.size.width-20,messageLabel.frame.size.height );
[self addSubview:messageLabel];
}
return self;
}
Why doesn't view2 appear in this code? In the result I see the local View1 label shown, at the top with a red border, and within the overall green border, however I see nothing of view2? That is the label with text "View2 Label Text", does NOT appear.
test11ViewController.m
#implementation test11ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
View1 *view1 = [[[View1 alloc] initWithFrame:CGRectMake(0.0, 0.0, 400, 100) ] autorelease];
view1.layer.borderColor = [UIColor redColor].CGColor;
view1.layer.borderWidth = 1;
[self.view addSubview:view1];
}
#end
View1.m
#implementation View1
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Local Label
CGFloat width = self.frame.size.width;
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, width, 30)] autorelease];
label.text = #"View1 Label Text";
label.layer.borderColor = [UIColor greenColor].CGColor;
label.layer.borderWidth = 1.0;
[self addSubview:label];
// External - Label2
View2 *view2 = [[[View2 alloc] initWithFrame:CGRectMake(0.0, 30, width, 30)] autorelease];
[super addSubview:view2];
}
return self;
}
#end
View2.m
#implementation View2
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
CGFloat width = self.frame.size.width;
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, width, 30)] autorelease];
label.text = #"View2 Label Text"; // Does NOT appear in output
label.layer.borderColor = [UIColor blueColor].CGColor;
label.layer.borderWidth = 1.0;
}
return self;
}
#end
view2 isn't actually adding the label to itself. You're missing this:
[self addSubview:label];
In other words, try:
#implementation View2
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
CGFloat width = self.frame.size.width;
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, width, 30)] autorelease];
label.text = #"View2 Label Text"; // Does NOT appear in output
label.layer.borderColor = [UIColor blueColor].CGColor;
label.layer.borderWidth = 1.0;
[self addSubview:label]; // NEW LINE HERE
}
return self;
}
#end
In your test view controller line after...
[self.view addSubview:view1];
...add...
[self.view sendSubviewToBack:view1];
Does view2 show now? Alertnately, set the alpha of both views to 0.5 to make sure one is not obscuring the other.
In my project i'm using a UITextField which is embedded into a plain white UIButton with rounded corners in order to create a "beautiful" text field. This code is used several times in different views so I decided to create a custom UIView for this purpose. The code for this custom UIView:
BSCustomTextField.h
#import <Foundation/Foundation.h>
#interface BSCustomTextField : UIView {
UIButton* btnTextFieldContainer;
UITextField* textField;
NSString* text;
}
#property (retain, nonatomic) UIButton* btnTextFieldContainer;
#property (retain, nonatomic) UITextField* textField;
#property (retain, nonatomic) NSString* text;
-(id)initWithPosition:(CGPoint)position;
#end
BSCustomTextField.m
#import "BSCustomTextField.h"
#import <QuartzCore/QuartzCore.h>
#implementation BSCustomTextField
#synthesize btnTextFieldContainer, textField, text;
-(id)initWithPosition:(CGPoint)position{
if (self == [super init]) {
btnTextFieldContainer = [[UIButton alloc] initWithFrame:CGRectMake(position.x, position.y, 260, 50)];
btnTextFieldContainer.backgroundColor = [UIColor whiteColor];
[[btnTextFieldContainer layer] setCornerRadius:3.];
[[btnTextFieldContainer layer] setMasksToBounds:YES];
[[btnTextFieldContainer layer] setBorderWidth:0.];
textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, 240, 30)];
textField.backgroundColor = [UIColor whiteColor];
textField.clearButtonMode = UITextFieldViewModeAlways;
textField.returnKeyType = UIReturnKeySend;
textField.keyboardType = UIKeyboardTypeEmailAddress;
textField.font = [UIFont fontWithName:#"Helvetica-Bold" size:20.];
[btnTextFieldContainer addSubview:textField];
[self addSubview:btnTextFieldContainer];
}
return self;
}
-(void)dealloc{
[btnTextFieldContainer release];
[textField release];
[super dealloc];
}
#end
So, when using this view in the viewDidLoad of the container view (see code below) the view is properly rendered on the desired position and looks exactly as specified but it does not react on touch events and thus does not become first responder when touched.
Code:
searchTextField = [[BSCustomTextField alloc] initWithPosition:CGPointMake(30, 150)];
searchTextField.textField.placeholder = NSLocalizedString(#"lsUserName", #"");
[[(BSPlainHeaderWithBackButtonView*)self.view contentView] addSubview:searchTextField];
Calling [searchTextField.textField becomeFirstResponder] programmatically works properly and makes the keyboard to appear.
But, the interesting part is, if I embed the code of BSCustomTextField inline in my container just like this:
UIButton* btnTextFieldContainer = [[UIButton alloc] initWithFrame:CGRectMake(30, 150, 260, 50)];
btnTextFieldContainer.backgroundColor = [UIColor whiteColor];
[[btnTextFieldContainer layer] setCornerRadius:3.];
[[btnTextFieldContainer layer] setMasksToBounds:YES];
[[btnTextFieldContainer layer] setBorderWidth:0.];
searchTextField = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, 240, 30)];
searchTextField.backgroundColor = [UIColor whiteColor];
searchTextField.clearButtonMode = UITextFieldViewModeAlways;
searchTextField.returnKeyType = UIReturnKeySend;
searchTextField.keyboardType = UIKeyboardTypeEmailAddress;
searchTextField.font = [UIFont fontWithName:#"Helvetica-Bold" size:20.];
searchTextField.placeholder = NSLocalizedString(#"lsUserName", #"");
[btnTextFieldContainer addSubview:searchTextField];
[[(BSPlainHeaderWithBackButtonView*)self.view contentView] addSubview:btnTextFieldContainer];
[btnTextFieldContainer release];
everything works as expected and the textfield reacts on touches. The type of the searchTextField is properly set in the header file for each case. The only difference is that in the first case I have an additional wrapping UIView on the UIButton and the UITextFiled. I have no idea what to do to make the text field to become first responder on touch.
Thanks a lot in advance,
Roman
Ok, I've got the solution. raaz's point to the UIResponder class tipped me off to the idea that there must be something wrong in the responder chain, thus I did a little research and found this topic: Allowing interaction with a UIView under another UIView in which exact the same problem is discussed.
Here is the new working code for BSCustomTextField.m
#import "BSCustomTextField.h"
#import <QuartzCore/QuartzCore.h>
#implementation BSCustomTextField
#synthesize btnTextFieldContainer, textField, text;
-(id)initWithPosition:(CGPoint)position{
if (self == [super init]) {
btnTextFieldContainer = [[UIButton alloc] initWithFrame:CGRectMake(position.x, position.y, 260, 50)];
btnTextFieldContainer.backgroundColor = [UIColor whiteColor];
[[btnTextFieldContainer layer] setCornerRadius:3.];
[[btnTextFieldContainer layer] setMasksToBounds:YES];
[[btnTextFieldContainer layer] setBorderWidth:0.];
textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, 240, 30)];
textField.backgroundColor = [UIColor whiteColor];
textField.clearButtonMode = UITextFieldViewModeAlways;
textField.returnKeyType = UIReturnKeySend;
textField.keyboardType = UIKeyboardTypeEmailAddress;
textField.font = [UIFont fontWithName:#"Helvetica-Bold" size:20.];
[btnTextFieldContainer addSubview:textField];
[self addSubview:btnTextFieldContainer];
}
return self;
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
// UIView will be "transparent" for touch events if we return NO
return YES;
}
-(void)dealloc{
[btnTextFieldContainer release];
[textField release];
[super dealloc];
}
#end
Since the clickable area fills out the entire BSCustomTextField view we can simply return YES in pointInside:withEvent:
Thank you all for pointing me into the right direction.
Refer UIResponder class
This class has instance method becomeFirstResponder: & isFirstResponder:
Also do not forget to set textfield editing property to YES
Oh, you're completely wrong with doing this way. You should add stretchable image into UIImageView and put it below UITextField.
UIImage *backgroundImage = [[UIImage imageNamed:#"fieldBackground.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0];
Or you can try to disable userInteraction in UIButton.