iOS UI Customization optimization - ios

I'm about to begin a big project which will contains a lot of UI customization.
For example, I need an UIView which will look like that :
So I wrote an UIView custom class but i really don't know if my code is optimized and if there are best ways to do that, so could you give me some advice plz ?
Here's my code :
// DPIViewHeader.h
#define HEADER_HEIGHT 30.0f
#define HEADER_COLOR [UIColor colorWithRed:161.0f/255.0f green:209.0f/255.0f blue:249.0f/255.0f alpha:1.0f]
#define BORDER_WIDTH 2.0f
#define BORDER_COLOR [[UIColor colorWithRed:82.0f/255.0f green:159.0f/255.0f blue:210.0f/255.0f alpha:1.0f] CGColor]
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface DPIViewWithHeaderTest : UIView
// properties
#property (strong, nonatomic) NSString *title;
#property (strong, nonatomic) UIColor *headerColor;
#property (strong, nonatomic) UIView *headerView;
#property (strong, nonatomic) UIView *contentView;
// methods
- (id)initWithFrame:(CGRect)frame title:(NSString *)title;
- (id)initWithFrame:(CGRect)frame title:(NSString *)title headerColor:(UIColor *)headerColor;
#end
// DPIViewHeader.m
#import "DPIViewWithHeaderTest.h"
#implementation DPIViewWithHeaderTest
- (id)initWithFrame:(CGRect)frame title:(NSString *)title {
self = [super initWithFrame:frame];
if (self) {
self.title = title;
}
return self;
}
- (void)layoutSubviews {
// set header view and content view
self.headerView = [[UIView alloc] initWithFrame:CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.frame.size.width, HEADER_HEIGHT)];
self.contentView = [[UIView alloc] initWithFrame:CGRectMake(self.bounds.origin.x, self.bounds.origin.y + HEADER_HEIGHT, self.frame.size.width, self.frame.size.height - HEADER_HEIGHT)];
// add title label
UILabel *label = [[UILabel alloc] init];
label.text = self.title;
[label sizeToFit];
label.center = CGPointMake(label.frame.size.width/2 + 10, self.headerView.frame.size.height/2);
label.backgroundColor = [UIColor clearColor];
[self.headerView addSubview:label];
// set color header
self.headerView.backgroundColor = HEADER_COLOR;
// set border attributes
self.layer.borderWidth = BORDER_WIDTH;
self.layer.borderColor = BORDER_COLOR;
self.headerView.layer.borderWidth = BORDER_WIDTH;
self.headerView.layer.borderColor = BORDER_COLOR;
// add subviews
[self addSubview:self.headerView];
[self addSubview:self.contentView];
}
#end

It really depends (like everything :) ) .
Let me tell you why using two scenarios:
The View is non-customisable:
If DPIViewWithHeaderTest is going to be embedded in a UITableViewCell, then well, scroll performance will be terrible due to high memory usage. Therefore improper for this purpose.
The next scenario: just a simple view, somewhere, with a static background, and some data. It's OK than, but not the best solution.
Good Solution
For both purposes I would suggest creating images. A prerendered image is cached and leaves very small memory footprint. Moreover in this case you could even create strechable one. Isn't this great ?
What if a UIView has to be customisable (like colour, size) ? Then this is the only solution but I would consider rewriting the implementation depending on purpose.
If there are going to be lots of such views, they are animated, for example this is a background of UITableViewCell you should consider drawing them using QuartzCore/Core Graphics for better performance.
For just one (or few) view, this implementation is just fine :) .
Last piece of advice
Generally, unless the view is to be customisable, I would suggest creating images.
For three reasons: performance, look and easiness of creation. Believe me, well crafted images look way better than custom drawing :)

Related

AutoLayout without usage of Storyboards or Interface Builder

I am building an app where I want to completely avoid using Storyboard and Interface Builder in general, so all UI should be specified in code. I am using PureLayout, a nice API for configuring AutoLayout constraints.
However, my issue is that it seems like AutoLayout is disabled when not using Interface Builder. updateViewConstraints, the method where I put the layout according to the recommendation given by the PureLayout author, is not called at all.
Just to give a bit more info about my setup:
deleted Main.storyboard and removed the entry from my Info.plist
manually setup self.window in AppDelegate.m and added UINavigationController with MainMainController as rootViewController
As mentioned, my main issue is that updateViewConstraints does not get called on MainViewController but the UI elements are all displayed with the frames that I passed to them during initilization.
Note: It seems to me like I just need to enable some flag somewhere to mimic the checkbox from Interface Builder with which you can indicate whether you want to use AutoLayout.
MainViewController.m
#interface MainViewController ()
#property (nonatomic, strong) UIButton *startButton;
#property (nonatomic, assign) BOOL didSetupConstraints;
#end
#implementation MainViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view addSubview:self.startButton];
[self.view setTranslatesAutoresizingMaskIntoConstraints:NO];
}
- (UIButton *)startButton
{
if (!_startButton) {
UIButton *startButton = [UIButton buttonWithType:UIButtonTypeSystem];
CGRect startButtonFrame = CGRectMake(75.0, 75.0, 250.0, 44.0);
startButton.frame = startButtonFrame;
[startButton setTitle:#"Start" forState:UIControlStateNormal];
[startButton setTranslatesAutoresizingMaskIntoConstraints:NO];
_startButton = startButton;
}
return _startButton;
}
- (void)updateViewConstraints
{
NSLog(#"Update view contraints");
if (!self.didSetupConstraints) {
[self.startButton autoCenterInSuperview];
self.didSetupConstraints = YES;
}
[super updateViewConstraints];
}
#end

Reuse UITableView code?

I have two view controllers, both of which contain table views. I would like to reuse the code because they are identical, and would like to keep things clean (as well as keep some data from the view controller). How can I go about doing this? Is it "allowed" so to speak, or is it frowned upon?
CustomTableView.h:
#interface CustomTableView : UITableView
#property (nonatomic, strong) NSString *someCoolString;
#property (nonatomic, strong) UIColor *superDuperColor;
#end
CustomTableView.m:
#import "CustomTableView.h"
#implementation CustomTableView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code
self.someCoolString = #"theString";
self.superDuperColor = [UIColor colorWithRed:48.0/255.0 green:32.0/255.0 blue:100.0/255.0 alpha:1.0];
}
return self;
}
#end
You should create a subclass of UITableView.

ImageView`s method setCenter not word in storyboard

I want to Initialize ImageView`s location in viewDidLoad method so i wrote below
//ViewController.h
//logoImage linked in storyboard
#property (weak, nonatomic) IBOutlet UIImageView *logoImage;
//ViewController.m
#synthesize logoImage;
- (void)viewDidLoad
{
[super viewDidLoad];
[logoImage setCenter: CGPointMake(self.view.center.x, self.view.center.y*0.7)];
[logoImage setBackgroundColor:[UIColor redColor]];
}
color changed well, but location doesn`t changed.
I want to know why and how to fix it
thank you for reading my ugly english.
hope you understand my question...

iOS: Issue modifying button's color

I have the following code in .h file:
#import <UIKit/UIKit.h>
#interface SCLoginViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIButton *btnLogin;
#end
and the following code in .m file:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Do any additional setup after loading the view from its nib.
// Add gradient to the buttons
btnLogin.layer.cornerRadius = 10;
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = btnLogin.layer.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:
(id)[UIColor colorWithWhite:1.0f alpha:0.1f].CGColor,
(id)[UIColor colorWithWhite:0.4f alpha:0.5f].CGColor,
nil];
gradientLayer.cornerRadius = btnLogin.layer.cornerRadius;
[btnLogin.layer addSublayer:gradientLayer];
// Add shadow
btnLogin.layer.shadowColor = [UIColor darkGrayColor].CGColor;
btnLogin.layer.shadowOpacity = 1.0;
btnLogin.layer.shadowOffset = CGSizeMake(2.0, 2.0);
}
This is how the button sits on the screen:
Something is horribly wrong though. I know I am missing something simple, but can't figure it out. I created regular outlet called btnLogin but any change I try to make to it is not working. The button is rounded rect button. I tried Custom button and that didn't help.
Thank you!
From the image, I see that you did not make a connection from your btnLogin on the nib file to the file's owner - .h file. So this line below has no connection to the button that you are trying to make changes.
#property (weak, nonatomic) IBOutlet UIButton *btnLogin;
Once you make that proper connection, it should show up the btnLogin name where Referencing Outlets is on the image you provided.

iOS5 adding and manipulting a UIView class

I have create a UIVeiw class and a .xib. Within this .xib view I have its set to freeform with the dimensions of 400x200 and I have assigned it to my custom class with the same name:
Storyboard: blogView
Class Files: blogView.h & blogView.m
Within in the .xib i have added a label and a text field and linked them up to variable within the .h files etc (See code below).
blogCont.h
#import <UIKit/UIKit.h>
#interface blogCont : UIView
#property (strong, nonatomic) IBOutlet UILabel *lbBlogDate;
#property (strong, nonatomic) IBOutlet UITextView *txtBlogTitle;
#end
blogCont.m
#import "newsStoryView.h"
#implementation blogCont
#synthesize lbBlogDate;
#synthesize txtBlogTitle;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code place a log to see if it loads
NSLog(#"View Loaded");
}
return self;
}
#end
Now with in my main viewController.m file i have added the following code to init this view class, and I have added a background colour to see if this loads in.
viewController.m
UIView *blogCont = [[blogView alloc] init];
blogCont.backgroundColor = [UIColor purpleColor];
[subview addSubview:blogCont];
Now when I run this it all works well but as I do not see the purple background it looks as if the view does not load, but within the log I do see the NSLog message I have within this view NSLog(#"View Loaded"); so it seems it initiating this, but I cannot for the life of me get this to display?
Now if I change the code slightly to my main View Controller.m fiel to:
CGRect blogFrame;
blogFrame.origin.x = 20;
blogFrame.origin.y = 20;
blogFrame.size = CGRectMake(400,200);;
newsStoryView *blogCont = [[blogView alloc] blogFrame];
blogCont.backgroundColor = [UIColor purpleColor];
[subview addSubview:blogCont];
Then I get my view display a nice purple box, so this shows up when I set a frame size and the init the view with it 'blogFrame', bu tI thought that all this would be set within the .xib settings so no need to do this?
SO how can I create this external view class and assign it into another view and then manipulate its data, as accessing the label in the .xib using blogCont.lbBlogDate.text does not seem to work that is it probably does but as I cannot view it i cannot confirm it.
What am i doing wrong?
Thanks
Seems I nearly answered my own question then did:
I was not setting the size within my separate class view I was asking for a size when init it:
- (id)initWithFrame:(CGRect)frame
this is asking for a size
so I could do the following to the above:
- (id)init
{
self = [super initWithFrame:CGRectMake(0, 0, 478, 220)];
.... rest of code
Setting the size within the view load.
But I could also set it when I init it in my main view controller as below:
newsStoryView *blogCont = [[blogView alloc] initWithFrame:CGRectMake(0, 0, 400, 200)];
This is better as I can control the position of each one. Hope this helps anyone

Resources