How do you make methods that work across multiple views? For example. I created this:
- (void)setPageTitle:(UILabel *)title withText:(NSString *)text
{
UIColor *pageTextColor = [UIColor colorWithRed:18.0/255.0 green:79.0/255.0 blue:118.0/255.0 alpha:1.0];
// Set page title
UIFont *font = [UIFont fontWithName:#"PassionOne-Regular" size:23];
[title setFont:font];
[title setText: text];
title.textColor = pageTextColor;
title.shadowColor = [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0];
title.shadowOffset = CGSizeMake(0, 1);
CGRect titleRect = [title textRectForBounds:title.bounds limitedToNumberOfLines:999];
CGRect tr = title.frame;
tr.size.height = titleRect.size.height;
title.frame = tr;
}
I want to be able to call the setPageTitle method on UILabels within different views. How do I go about doing this? Where do I put this code to make it work? I only want to put it in 1 file and have it work in different views. Thank you.
I would suggest making this a category on the UIView class.
UIView+PageTitle.h
#interface UIView (PageTitle)
- (void)setPageTitle:(UILabel *)title withText:(NSString *)text;
#end
UIView+PageTitle.m
#import "UIView+PageTitle.h"
#implementation UIView (PageTitle)
- (void)setPageTitle:(UILabel *)title withText:(NSString *)text {
// your implementation
}
#end
What you probably are looking for is either you create a subclass of a UIViewController (I believe is what you are using) and make it your class MyUIViewController with that one as a method, or, you can create a category of the UIViewController and add that method. Here is an explanation on how to create a category, plus some useful info. A category is an extension of the capabilities of a class, pretty much what you are trying to do.
If you want to use a category you should at least create a useful category. A instance method in a category that doesn't use self is misplaced.
Since you are manipulating a UILabel you should make that a UILabel category.
#interface UILabel (PageTitle)
- (void)setPageTitle:(NSString *)text {
UIColor *pageTextColor = [UIColor colorWithRed:18.0/255.0 green:79.0/255.0 blue:118.0/255.0 alpha:1.0];
// Set page title
UIFont *font = [UIFont fontWithName:#"PassionOne-Regular" size:23];
[self setFont:font];
[self setText: text];
self.textColor = pageTextColor;
self.shadowColor = [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0];
self.shadowOffset = CGSizeMake(0, 1);
CGRect titleRect = [self textRectForBounds:self.bounds limitedToNumberOfLines:999];
CGRect tr = self.frame;
tr.size.height = titleRect.size.height;
self.frame = tr;
}
#end
use it like this:
UILabel *myLabel;
[myLabel setPageTitle:#"Foobar"];
Add quick way is to add a '+' making it a static method in another class:
UIKitUtilities.h
+ (void)setPageTitle:(UILabel *)title withText:(NSString *)text;
And in the m file:
+ (void)setPageTitle:(UILabel *)title withText:(NSString *)text { ...your code here... }
Related
I have create a custom UIView subclass which should draw a simple dashed line. To define the color of the line I have added an inspectable property lineColor
// LineView.h
#interface LineView : UIView
#property (nonatomic,assign) IBInspectable UIColor *lineColor;
#end
// LineView.m
- (id)initWithFrame:(CGRect)frame{
if((self = [super initWithFrame:frame])){
[self setupView];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder{
if((self = [super initWithCoder:aDecoder])){
[self setupView];
}
return self;
}
- (void)setupView {
self.lineColor = [UIColor colorWithRed:0 green:0 blue:255.0 alpha:1.0];
//self.lineColor = [UIColor blueColor]; <-- No Problem
[self refreshLine];
}
- (void)layoutSubviews {
[super layoutSubviews];
[self refreshLine];
}
- (void)refreshLine {
CGColorRef cgLineColor = self.lineColor.CGColor; // <--CRASH
...
}
If a color is assigned in the Interface Builder everything works fine
If a default color like [UIColor blueColor] is assigned everything works fine
If a custom color like [UIColor colorWithRed:0 green:0 blue:255.0 alpha:1.0] the app crashes with EXC_BAD_ACCESS
[UIDeviceRGBColor respondsToSelector:]: message sent to deallocated instance 0x6000022d08c0
Why is this?
When you use [UIColor blueColor], you don't create the object; you get a reference to it and something else manages its life cycle.
When you init a new UIColor object, you're responsible for making sure it is still valid when used. "assign" doesn't increase the object's reference count; "strong" does.
I'm drawing three rectangles in order to show the loading, however I want to input Alphabets in those rectangles, how can I put letters in that.
My Function:
- (void)configUI {
self.backgroundColor = [UIColor clearColor];
UIView *rect1 = [self drawRectAtPosition:CGPointMake(0, 0)];
UIView *rect2 = [self drawRectAtPosition:CGPointMake(20, 0)];
UIView *rect3 = [self drawRectAtPosition:CGPointMake(40, 0)];
[self addSubview:rect1];
[self addSubview:rect2];
[self addSubview:rect3];
[self doAnimateCycleWithRects:#[rect1, rect2, rect3]];
}
I want to insert the letter "A" in rect1, "B" in rect2 and "C" in rect3.
Use UILabel instead of UIView. Set the label text. (Note that a UILabel has a background color just like a UIView.)
To draw a string on view, you need to create a subclass of UIView. Import this view in your view controller and create above views as object of custom view.
In custom view there is a view override method -
- (void)drawRect:(CGRect)rect;
This is the place where you can draw string and set attributes for drawing.
For example: Custom view class
CustomView.h
#import <UIKit/UIKit.h>
#interface CustomView : UIView
#property (nonatomic, strong) NSString *drawString;
#end
CustomView.m
#import "CustomView.h"
#implementation CustomView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (void)drawRect:(CGRect)rect {
NSMutableParagraphStyle *textStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
textStyle.lineBreakMode = NSLineBreakByClipping;
textStyle.alignment = NSTextAlignmentCenter;
NSDictionary *attributes = #{
NSParagraphStyleAttributeName: textStyle,
// Text font
NSFontAttributeName : [UIFont fontWithName:#"HelveticaNeue" size:20.0],
// Text color
NSForegroundColorAttributeName : [UIColor orangeColor]
};
[self.drawString drawInRect:rect withAttributes:attributes];
}
#end
Now in your code create view object type of this custom class:
- (void)configUI {
self.backgroundColor = [UIColor clearColor];
CustomView *rect1 = [self drawRectAtPosition:CGPointMake(0, 0)];
CustomView *rect2 = [self drawRectAtPosition:CGPointMake(20, 0)];
CustomView *rect3 = [self drawRectAtPosition:CGPointMake(40, 0)];
// This will draw text to view
[rect1 setDrawString:#"A"];
[rect2 setDrawString:#"B"];
[rect3 setDrawString:#"C"];
[rect1 setBackgroundColor:[UIColor whiteColor]];
[rect2 setBackgroundColor:[UIColor whiteColor]];
[rect3 setBackgroundColor:[UIColor whiteColor]];
[self addSubview:rect1];
[self addSubview:rect2];
[self addSubview:rect3];
[self doAnimateCycleWithRects:#[rect1, rect2, rect3]];
}
i'm having an edit button which is connected to this method. In this method i want to make the textView editable and change the background. The problem is the background do not seem to change. Why is that?
ViewDidLoad
self.aboutText.backgroundColor = [UIColor clearColor];
self.aboutText.delegate = self;
self.aboutText.editable = NO;
method
-(IBAction)editField:(id)sender {
self.aboutText.backgroundColor = [UIColor whiteColor];
self.aboutText.editable = YES;
}
Okay the issue was i only did set the action and not the target.
All i did was set the target to self.
sorry for the inconvenience
Try the following:
//.h file
#interface AddEntryViewController : UIViewController<UITextViewDelegate>{}
//.m file
//viewDidLoad
_aboutText.delegate = self;
//add the following method
-(void) textViewDidBeginEditing:(UITextView *)textView
{
[textView setTextColor: [UIColor blackColor]];
}
I would like to intercept a touch on a UITextField, for instance when I first load it I give it a #selector() to load a different method instead of the delegate stuff?
This is my attempt:
descriptionText = [[UITextField alloc] initWithFrame:CGRectMake(10.0, 25.0, infoView.frame.size.width - 20, 100.0)];
descriptionText.backgroundColor = [UIColor whiteColor];
descriptionText.textColor = [UIColor blackColor];
descriptionText.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
descriptionText.userInteractionEnabled = YES;
[descriptionText addTarget:self action:#selector(loadInfoView:) forControlEvents:UIControlEventTouchUpInside];
descriptionText.font = [UIFont fontWithName:#"Helvetica" size:15];
// show view
[infoView addSubview:descriptionText];
However when I debug the method:
- (void)loadInfoView
{
NSLog(#"load other view here");
}
Your problem is in the forControlEvents:: try UIControlEventEditingDidBegin
[descriptionText addTarget:self action:#selector(loadInfoView:) UIControlEventEditingDidBegin];
Your #selector(loadInfoView:) is also wrong if you have - (void)loadInfoView
or #selector(loadInfoView:) and - (void)loadInfoView: (id) sender
or #selector(loadInfoView) and - (void)loadInfoView
However, why you don't use the UITextFieldDelegate?
.m
#interface ViewController () <UITextFieldDelegate>
#property (strong, nonatomic) UITextField *descriptionText;
#end
Remember to:
self.descriptionText.delegate = self;
Then:
-(void) textFieldDidBeginEditing:(UITextField *)textField
{
if (textField == self.descriptionText)
{
[self loadInfoView];
}
}
Keyboard:
If you don't want to show the keyboard you need to add a [descriptionText resignFirstResponder];
I'm not sure you can get actions to be called on a text field on touch like you want.
If that doesn't work, why don't you attach a tap gesture recognizer to your text field?
I overrode (is that a real word? regardless) my UITableView headers with a common used UIView to be used across the app.
Its no biggie, just a back solid background, pre-selected font, font size, font weight, font color, etc. Thats REALLY all there is too it. In fact heres the UIView
TableSectionView.h
#import <UIKit/UIKit.h>
#interface TableSectionView : UIView {
NSString *textLabel;
UIColor *textColor;
UIColor *backgroundColor;
BOOL bold;
NSString *textFont;
NSInteger textSize;
}
#property (nonatomic, retain) NSString *textLabel, *textFont;
#property (nonatomic, retain) UIColor *textColor, *backgroundColor;
#property (nonatomic) BOOL bold;
#property (nonatomic) NSInteger textSize;
- (id)initWithFrame:(CGRect)frame andText:(NSString*)text;
#end
TableSectionView.m
#import "TableSectionView.h"
#implementation TableSectionView
#synthesize textLabel, backgroundColor, textColor, bold, textFont, textSize;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(id)initWithFrame:(CGRect)frame andText:(NSString *)text {
self = [self initWithFrame:frame];
if(self) {
textLabel = text;
textFont = #"Arial-BoldMT";
textSize = 16;
textColor = [[UIColor alloc] initWithRed:1 green:1 blue:1 alpha:1];
backgroundColor = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:0.8];
}
return self;
}
-(void)layoutSubviews {
[super layoutSubviews];
UILabel *title = [[UILabel alloc] initWithFrame:self.frame];
title.text = [NSString stringWithFormat:#" %#", textLabel];
title.font = [UIFont fontWithName:textFont size:textSize];
title.textColor = textColor;
title.backgroundColor = backgroundColor;
[self addSubview:title];
}
#end
and how i use it in a file:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return [[TableSectionView alloc] initWithFrame:CGRectZero andText:#"Table Section Title"];
}
Nothing strange or unique here.
And this works, theres no problem with it showing up just fine. What happens is when you scroll the table view.
When you scroll up, the section header shifts down and stays there. The harder the velocity, the more the section header shifts down and stays there until you go back down to the top of the table.
This app has about 25 separate table views this header is to be apart of, and I really want to squash this rendering bug asap.
I wanted to post a screenshot, but due to a strict NDA, I am not allowed to without running risk of being fired.
But here is SOMETHING to visualize the problem. Ive blurred out all of the text, sorry I had no other choice :\
The black bar is the section header, the top of the image is the top of the UITableView. Notice how much that section header is DOWN, vs where it is supposed to be? (the top, like normal section headers). Im just not sure what to do here
I think your problem is here:
-(void)layoutSubviews {
[super layoutSubviews];
UILabel *title = [[UILabel alloc] initWithFrame:self.frame];
title.text = [NSString stringWithFormat:#" %#", textLabel];
title.font = [UIFont fontWithName:textFont size:textSize];
title.textColor = textColor;
title.backgroundColor = backgroundColor;
[self addSubview:title];
}
Adding subviews in layoutSubviews is odd. Why don't you do it in the initWithFrame to avoid confusing the rendering code of Cocoa?
EDIT: That also saves you from saving all those member vars, declaring all those properties & synthesizing them :)
EDIT 2: When you init the UILabel you should use as reference self.bounds instead of self.frame, too.