Does this code follow standard Objective-C and MVC conventions? [closed] - ios

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have written a basic app in Objective-C which displays a users contacts with pictures. The issue is, there is no compartmentalization and I feel I am violating certain standards.
Everything is handled through one main ViewController, which begins the work mainly after a user taps a button (through an outlet to IB).
//
// ViewController.m
// Future Take 4
//
// Created by Rooz Mahdavian on 5/31/13.
// Copyright (c) 2013 Rooz Mahdavian. All rights reserved.
//
#import "ViewController.h"
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
#import <QuartzCore/QuartzCore.h>
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(userAllowedForAccess)];
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
[[self.view viewWithTag:300] addGestureRecognizer:singleTap];
[[self.view viewWithTag:300] setUserInteractionEnabled:YES];
CGRect tempButton = [self.view viewWithTag:300].frame;
tempButton.origin.y = self.view.frame.size.height/2 - 56;
[self.view viewWithTag:300].frame = tempButton;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration: .4];
[UIView setAnimationDelay: 0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CGRect tempButton2 = [self.view viewWithTag:300].frame;
tempButton2.origin.y += 90;
[self.view viewWithTag:300].frame = tempButton2;
[self.view viewWithTag:100].alpha = 1;
[UIView commitAnimations];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)userAllowedForAccess {
NSLog(#"User Has Verified Contacts");
UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0,0, 320, 55)];
header.backgroundColor = [UIColor colorWithRed:34/255.0 green:34/255.0 blue:34/255.0 alpha:1];
[header.layer setShadowColor:[UIColor colorWithRed:14/255.0 green:14/255.0 blue:14/255.0 alpha:.5].CGColor];
[header.layer setShadowOpacity:0];
[header.layer setShadowRadius:3.0];
[header.layer setShadowOffset:CGSizeMake(2.0, 2.0)];
[self.view addSubview:header];
[self.view bringSubviewToFront:[self.view viewWithTag:100]];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration: .7];
[UIView setAnimationDelay: 0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CGRect tempLogo = [self.view viewWithTag:100].frame;
tempLogo.origin.y = -14;
tempLogo.size.height = tempLogo.size.height/2.5;
tempLogo.size.width = tempLogo.size.width/2.5;
tempLogo.origin.x = 160 - tempLogo.size.width/2;
[self.view viewWithTag:100].frame = tempLogo;
CGRect tempButton = [self.view viewWithTag:300].frame;
tempButton.size.width = tempButton.size.width * 2.5;
tempButton.size.height = tempButton.size.height * 2.5;
tempButton.origin.x = -((tempButton.size.width/2)-((tempButton.size.width * 2.5))/2);
[self.view viewWithTag:300].frame = tempButton;
[self.view viewWithTag:300].alpha = 0;
[self.view viewWithTag:200].alpha = 0;
[header.layer setShadowOpacity:1];
[UIView commitAnimations];
ABAddressBookRef addressBook = ABAddressBookCreate();
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 60, self.view.frame.size.width, self.view.frame.size.height)];
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
accessGranted = granted;
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );
int peopleInARow = 0;
int maxPeopleInARow = 3;
int positionFromTop = 20;
int IMAGE_SIZE = 70;
float animationOffset = .5;
float animationOffsetChange = .3;
float animationDuration = .5;
int scaleOffset = 40;
int screenWidth = 320;
int startingPositionFromLeft = 26;
int positionFromLeft = startingPositionFromLeft;
int topOffset = 40;
int leftOffset = 26;
int numberOfRows = 0;
UIView *contactContainer;
UIImage* image;
CALayer * l;
NSString* name;
NSString* lastName;
NSString* firstName;
UIImageView *newimageview;
UILabel *label;
UIView *contactImageContainer;
for ( int i = 0; i < nPeople; i++ )
{
ABRecordRef person = CFArrayGetValueAtIndex( allPeople, i );
firstName = (__bridge_transfer NSString*)ABRecordCopyValue(person,
kABPersonFirstNameProperty);
lastName = (__bridge_transfer NSString*)ABRecordCopyValue(person,
kABPersonLastNameProperty);
name = [NSString stringWithFormat:#"%# %#", firstName, lastName];
if(ABPersonHasImageData(person)){
//NSLog(#"%#", name);
image = [UIImage imageWithData:(__bridge NSData *)ABPersonCopyImageData(person)];
//NSLog(#"Position %i", positionFromLeft);
newimageview = [[UIImageView alloc] initWithFrame:CGRectMake(-scaleOffset/2, -scaleOffset/2, IMAGE_SIZE+scaleOffset, IMAGE_SIZE+scaleOffset)];
newimageview.contentMode = UIViewContentModeScaleAspectFit;
[newimageview setImage: image];
contactContainer = [[UIView alloc] initWithFrame:CGRectMake(positionFromLeft, positionFromTop + 20, IMAGE_SIZE, 200)];
contactImageContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, IMAGE_SIZE, IMAGE_SIZE)];
contactImageContainer.clipsToBounds = YES;
l = [contactImageContainer layer];
[l setMasksToBounds:YES];
[l setCornerRadius:IMAGE_SIZE/2];
// You can even add a border
[l setBorderWidth:0.0];
[l setBorderColor:[[UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:.6] CGColor]];
[contactImageContainer addSubview:newimageview];
[contactContainer addSubview:contactImageContainer];
label = [[UILabel alloc] initWithFrame: CGRectMake(0, IMAGE_SIZE + 10, IMAGE_SIZE, 20)];
label.text = firstName;
label.backgroundColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0];
label.textColor = [UIColor whiteColor];
[label setTextAlignment:NSTextAlignmentCenter];
[label setFont:[UIFont fontWithName:#"Arial-BoldMT" size:14]];
[contactContainer addSubview:label];
contactContainer.alpha = 0;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationDelay:animationOffset];
animationOffset+= animationOffsetChange;
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
contactContainer.alpha = 1;
CGRect temp = contactContainer.frame;
temp.origin.y = positionFromTop;
contactContainer.frame = temp;
[UIView commitAnimations];
if(peopleInARow >= 2){
positionFromTop += IMAGE_SIZE + topOffset;
peopleInARow = 0;
positionFromLeft = startingPositionFromLeft;
numberOfRows++;
} else {
peopleInARow += 1;
positionFromLeft += IMAGE_SIZE + leftOffset;
}
[scroll addSubview:contactContainer];
[scroll bringSubviewToFront:contactContainer];
}
}
NSLog(#"%i", numberOfRows);
scroll.contentSize = CGSizeMake(screenWidth, 150 * numberOfRows);
scroll.pagingEnabled = NO;
[self.view addSubview:scroll];
[self.view bringSubviewToFront:scroll];
}
- (IBAction)userDeniedAccess:(id)sender {
NSLog(#"Denied");
}
#end
Can anyone tell me the best way to rewrite this and what standard/conventions (probably in MVC) I am doing wrong?

You're not violating MVC at any thing. The view controller loads some contacts and displays them in the view. The model, represented by the contact, and the views have no coupling at all. That's correct from MVC's point of view.
As you said, this is a simple app. You may need to add some design to your code if the applications gets bigger and more complicated. But this design is good for such level of complexity. For example, if this class get bigger and more complex, you may separate the contacts loading part into a new class.
However, there's a very bad thing about your code. The method userAllowedForAccess contains more than 100 lines of code. Modularity must be maintained in the level of classes as well as methods and functions. Separate the code to many methods, depending on the function it performs. For example:
UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0,0, 320, 55)];
header.backgroundColor = [UIColor colorWithRed:34/255.0 green:34/255.0 blue:34/255.0 alpha:1];
[header.layer setShadowColor:[UIColor colorWithRed:14/255.0 green:14/255.0 blue:14/255.0 alpha:.5].CGColor];
[header.layer setShadowOpacity:0];
[header.layer setShadowRadius:3.0];
[header.layer setShadowOffset:CGSizeMake(2.0, 2.0)];
[self.view addSubview:header];
[self.view bringSubviewToFront:[self.view viewWithTag:100]];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration: .7];
[UIView setAnimationDelay: 0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
Can be extracted in a method called - (void) setupHeaderView and you can make another method to load the contacts - (NSArray *) getContacts or just - (NSArray *) contacts to match Objective-C's style for getters definition.

I would start refactoring your
- (IBAction)userAllowedForAccess
method in smaller and atomic methods. It's usually a bad idea to have one method that does basically everything.

Related

How to get original image when we zoom in and zoom out the image in ios

Hi i am beginner in ios and in my project i am adding UIImage on UIScrollview and i have added tap gesture on UIImage
When we double click on UIImage then image should be zooming full screen size on view controller
After the full screen size image we can zoom it like any way what we want(i mean using like pinch zoom effect)here my requirement is when we double click on image then image need to set it's original position i have tried my level best but i did not get result please help me
my code is below:
#import "ViewController2.h"
#interface ViewController2 ()
{
UIScrollView * myScroll;
UITapGestureRecognizer *tap;
BOOL isFullScreen;
CGRect prevFrame;
UIImageView * _imageView;
}
#end
#implementation ViewController2
- (void)viewDidLoad
{
[super viewDidLoad];
isFullScreen = FALSE;
myScroll = [[UIScrollView alloc] init];
myScroll.frame = self.view.bounds;
myScroll.contentSize = CGSizeMake(_imageView.frame.size.width, _imageView.frame.size.height);
myScroll.maximumZoomScale = 4.0;
myScroll.minimumZoomScale = 1.0;
myScroll.clipsToBounds = YES;
myScroll.delegate = self;
myScroll.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:myScroll];
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 300, 200)];
_imageView.contentMode = UIViewContentModeScaleAspectFill;
[_imageView setClipsToBounds:YES];
_imageView.userInteractionEnabled = YES;
_imageView.image = [UIImage imageNamed:#"ram.jpeg"];
UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imgToFullScreen:)];
tapper.numberOfTapsRequired = 1;
[_imageView addGestureRecognizer:tapper];
[myScroll addSubview:_imageView];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return _imageView;
}
-(void)imgToFullScreen:(UITapGestureRecognizer*)sender {
if (!isFullScreen) {
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
prevFrame = _imageView.frame;
[_imageView setFrame:[[UIScreen mainScreen] bounds]];
}completion:^(BOOL finished){
isFullScreen = TRUE;
}];
return;
}
else{
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
[_imageView setFrame:prevFrame];
}completion:^(BOOL finished){
isFullScreen = FALSE;
}];
return;
}
}
#end
I did some modifications in your code as like below try it .Check it give your wanted output or not.
#interface ScrollViewController ()<UIScrollViewDelegate>{
UIScrollView * myScroll;
UITapGestureRecognizer *tap;
BOOL isFullScreen;
CGRect prevFrame;
UIImageView * _imageView;
CGAffineTransform trans;
}
#end
#implementation ScrollViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
isFullScreen = FALSE;
myScroll = [[UIScrollView alloc] init];
myScroll.frame = [UIScreen mainScreen].bounds;
myScroll.contentSize = CGSizeMake(prevFrame.size.width, prevFrame.size.height);
myScroll.maximumZoomScale = 4.0;
myScroll.minimumZoomScale = 1.0;
myScroll.clipsToBounds = YES;
myScroll.delegate = self;
myScroll.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:myScroll];
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 300, 200)];
_imageView.contentMode = UIViewContentModeScaleAspectFill;
[_imageView setClipsToBounds:YES];
_imageView.userInteractionEnabled = YES;
_imageView.image = [UIImage imageNamed:#"img.png"];
UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imgToFullScreen:)];
tapper.numberOfTapsRequired = 2;
[_imageView addGestureRecognizer:tapper];
[myScroll addSubview:_imageView];
prevFrame = _imageView.frame;
trans = _imageView.transform;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return _imageView;
}
-(void)imgToFullScreen:(UITapGestureRecognizer*)sender {
if (!isFullScreen) {
myScroll.contentSize = prevFrame.size;
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
_imageView.frame = [UIScreen mainScreen].bounds;
}completion:^(BOOL finished){
isFullScreen = TRUE;
}];
return;
}
else{
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
myScroll.contentSize = CGSizeMake(prevFrame.size.width, prevFrame.size.height);
_imageView.transform = trans;
_imageView.frame = prevFrame;
NSLog(#"%# %#",NSStringFromCGSize(myScroll.contentSize),NSStringFromCGRect(prevFrame));
}completion:^(BOOL finished){
isFullScreen = FALSE;
}];
return;
}
}

UITableView Layout is Broken

I'm new to iOS development, and now working on an iOS app mainly using UINavigationController and UITableViewController.
The problem I try to solve is the UITableView (Custom tableView cell) layout broken bug on the root viewController. This happens when I back from a child viewController to the root viewController.(Left: Original, Right: Wrong Layout) It looks like UITableView position is moved for some reason, but I'm not sure why.
In MainViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
viewFrame = self.view.bounds;
[self loadHeader];
[self loadTable];
self.view.backgroundColor = [UIColor whiteColor];
numberOfCellRow = 20;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)loadView {
[super loadView];
}
- (void)loadHeader {
CGRect headerFrame = viewFrame;
headerFrame.size.width = self.view.frame.size.width;
headerFrame.size.height = 200;
self.headerView = [[HeaderView alloc] initWithFrame:CGRectIntegral(headerFrame)];
[self.view addSubview:self.headerView];
NSLog(#"header loaded");
}
- (void)loadTable {
CGRect tableFrame = CGRectMake(viewFrame.origin.x, viewFrame.origin.y + 150,
viewFrame.size.width, viewFrame.size.height-150);
self.customTableView = [[UITableView alloc] initWithFrame:CGRectIntegral(tableFrame)];
self.customTableView.backgroundColor = [UIColor clearColor];
//set delegates
self.customTableView.delegate = self;
self.customTableView.dataSource = self;
//set custom cell
UINib *nib = [UINib nibWithNibName:#"CardViewCell" bundle:nil];
[self.customTableView registerNib:nib forCellReuseIdentifier:#"Cell"];
self.customTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:self.customTableView];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"cell loaded");
dispatch_async(dispatch_get_main_queue(), ^{
[self loadData:indexPath];
});
}
- (void)loadData: (NSIndexPath *)indexPath {
_tableCell.titleLabel.text = [[_articles objectAtIndex:indexPath.row] title];
NSLog(#"%#", [[_articles objectAtIndex:indexPath.row] title]);
[_tableCell setNeedsLayout];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
_tableCell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
_tableCell.backgroundColor = [UIColor clearColor];
[_tableCell.contentView setUserInteractionEnabled: NO];
// add touch events
[_tableCell.button addTarget:self
action:#selector(cellPressed:withEvent:)
forControlEvents:UIControlEventTouchUpInside];
NSLog(#"%#", NSStringFromCGRect(tableView.frame));
return _tableCell;
}
In CardViewCell.m
- (void)drawRect:(CGRect)rect {
//self.backgroundColor = [UIColor colorWithRed:228/255.0f green:228/255.0f blue:228/255.0f alpha:1.0f];
NSLog(#"%f", rect.origin.x);
self.backgroundColor = [UIColor clearColor];
[self drawCardView];
[self drawCardImage];
[self drawButton];
[self drawLabels];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
self.selectionStyle = UITableViewCellSelectionStyleNone;
}
- (void)drawCardImage {
_cardViewBounds = _cardView.bounds;
CGRect imageFrame = _cardViewBounds;
imageFrame.size.height = _cardViewBounds.size.height/2+40;
_cardImage = [[UIImageView alloc] initWithFrame:CGRectIntegral(imageFrame)];
_cardImage.image = [UIImage imageNamed:#"sampleImage"];
_cardImage.backgroundColor = [UIColor grayColor];
_cardImage.clipsToBounds = YES;
_cardImage.contentMode = UIViewContentModeScaleAspectFill;
_cardImage.userInteractionEnabled = YES;
_cardImage.tag = 100;
UIBezierPath *maskPath;
maskPath = [UIBezierPath bezierPathWithRoundedRect:self.cardView.bounds
byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight)
cornerRadii:CGSizeMake(3.0, 3.0)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.cardView.bounds;
maskLayer.path = maskPath.CGPath;
_cardImage.layer.mask = maskLayer;
[self.cardView addSubview:_cardImage];
}
- (void)drawCardView {
CGRect screen = [[UIScreen mainScreen] bounds];
CGRect frame = CGRectMake(15, 25, (int)screen.size.width-30, 200);
_cardView.layer.cornerRadius = 3;
_cardView.backgroundColor = [UIColor greenColor];
_cardImage.userInteractionEnabled = YES;
_cardImage.tag = 101;
_cardView.frame = CGRectIntegral(frame);
CALayer *caLayer = _cardView.layer;
caLayer.frame = _cardView.frame;
caLayer.shadowRadius = 3.0f;
caLayer.shadowOpacity = 0.4f;
caLayer.shadowOffset = CGSizeMake(0.0f, 3.0f);
caLayer.shouldRasterize = YES;
// retina screen resolution
[caLayer setRasterizationScale:[[UIScreen mainScreen] scale]];
[caLayer setShouldRasterize:YES];
[self addSubview:_cardView];
}
- (void)drawButton {
CGRect buttonSize = CGRectMake(_cardViewBounds.size.width-100, _cardViewBounds.size.height/2+10, 50, 50);
_button = [[UIButton alloc] initWithFrame:CGRectIntegral(buttonSize)];
_button.layer.cornerRadius = 25;
_button.backgroundColor = [UIColor colorWithRed:0 green:169.0f/255.0f blue:244.0f/255.0f alpha:1.0f];
_button.userInteractionEnabled = YES;
_button.tag = 102;
//_button.titleLabel.text = #"+";
[_button setTitle:#"+" forState:UIControlStateNormal];
[_button.titleLabel setFont:[UIFont fontWithName:#"Helvetica" size:30.0]];
CALayer *caButtonLayer = _button.layer;
caButtonLayer.frame = _button.frame;
caButtonLayer.shadowRadius = 3.0f;
caButtonLayer.shadowOpacity = 0.2f;
caButtonLayer.shadowOffset = CGSizeMake(0.0f, 3.0f);
caButtonLayer.shouldRasterize = YES;
// retina screen resolution
[caButtonLayer setRasterizationScale:[[UIScreen mainScreen] scale]];
[caButtonLayer setShouldRasterize:YES];
[self.cardView addSubview:_button];
}
- (void)drawLabels {
CGRect titleLabelSize = CGRectMake( 10, _cardViewBounds.size.height-50, _cardViewBounds.size.width-20, 40);
_titleLabel = [[UILabel alloc] initWithFrame:CGRectIntegral(titleLabelSize)];
_titleLabel.backgroundColor = [UIColor clearColor];
_titleLabel.numberOfLines = 2;
_titleLabel.userInteractionEnabled = YES;
_titleLabel.tag = 103;
[_titleLabel setFont:[UIFont fontWithName:#"Helvetica" size:15.0]];
[_cardView addSubview:_titleLabel];
[_cardView sendSubviewToBack:_titleLabel];
}
- (void)prepareForReuse {
[super prepareForReuse];
for (UIView *subView in [self.contentView subviews]) {
[subView removeFromSuperview];
}
}
The code of this app is on this link.
Any ideas to solve this?
Your thoughts and help will be hugely appreciated.
the reason the view misplace is due to the _cardView.frame is CGRectZero when disappear, and I didn't find the solve yet.
you can add those to see the change.
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
NSLog(#"viewWillLayoutSubviews cardView %#",NSStringFromCGRect(self.tableCell.cardView.frame));
}
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
NSLog(#"viewDidLayoutSubviews cardView %#",NSStringFromCGRect(self.tableCell.cardView.frame));
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
NSLog(#"viewWillDisappear cardView %#",NSStringFromCGRect(self.tableCell.cardView.frame));
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
NSLog(#"viewDidDisappear cardView %#",NSStringFromCGRect(self.tableCell.cardView.frame));
}
I think you can learn more about life-cycle about viewController and Cell.
LifeCycle
by the way, when I watching your code, I don't know if you want to use xib or only code to programming. Like the code below, this is init from code but you try to get from xib.
just my opinion.
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
// make self from nib file
UINib *nib = [UINib nibWithNibName:#"HeaderView" bundle:nil];
self = [nib instantiateWithOwner:nil options:nil][0];
self.backgroundColor = [UIColor colorWithRed:0 green:169.0f/255.0f blue:244.0f/255.0f alpha:1.0f];
CGRect frame = CGRectZero;
frame.size.width = [[UIScreen mainScreen] bounds].size.width;
frame.size.height = 200;
[self setFrame:frame];
}
return self;
}

UIBezierPath Animation in UIView

I'm trying to make a animation that is done in Skype iOS application. The animation can be seen in this link Animation Section 3:Add a Contact
I tried with UIBezierPath but I can't do it. Any ideas?
Thanks!
My code
#implementation CustomView
#pragma mark - Lifecycle and initialize components
- (instancetype) initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if ( self ) {
self.alpha = 0;
[self configureCancelButton];
[self configureCollectionView];
[self addSubview:self.cancelButton];
[self addSubview:self.collectionView];
}
return self;
}
- (void) configureCancelButton {
self.cancelButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.cancelButton setTitle:#"Cancel" forState:UIControlStateNormal];
self.cancelButton.titleLabel.font = [UIFont systemFontOfSize:20];
[self.cancelButton addTarget:self action:#selector (cancelView) forControlEvents:UIControlEventTouchUpInside];
self.cancelButton.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.8];
self.cancelButton.layer.cornerRadius = 7.f;
self.frameForCancelButton = CGRectMake (self.bounds.origin.x+5, self.bounds.size.height - kCancelButtonHeight - 5, self.bounds.size.width-10, kCancelButtonHeight);
self.cancelButton.frame = CGRectMake (self.frameForCancelButton.origin.x, self.frameForCancelButton.origin.y + kAnimationOffset, self.frameForCancelButton.size.width, self.frameForCancelButton.size.height);
}
- (void) configureCollectionView {
UICollectionViewFlowLayout *layout= [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(kItemSize, kItemSize);
layout.minimumInteritemSpacing = 3.0;
layout.sectionInset = UIEdgeInsetsMake(0, 7, 7, 10);
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.frameForCollectionView = CGRectMake(self.cancelButton.frame.origin.x, self.frame.size.height - (self.cancelButton.frame.size.height + 10 + kCollectionHeight), self.cancelButton.bounds.size.width, kCollectionHeight);
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake (self.frameForCollectionView.origin.x, self.frameForCollectionView.origin.y + kAnimationOffset, self.frameForCollectionView.size.width, self.frameForCollectionView.size.height)
collectionViewLayout:layout];
self.collectionView.backgroundColor = [UIColor colorWithWhite:1 alpha:.8];
[self.collectionView registerClass:[RAShareCell class] forCellWithReuseIdentifier:#"Cell"];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
self.collectionView.layer.cornerRadius = 7.f;
}
#pragma mark - Public Methods
- (void) present {
[UIView animateWithDuration:0.35 animations:^{
self.alpha = 1;
self.darkView.alpha = .5;
}];
[UIView animateWithDuration:1.0 delay:0.45 options:(UIViewAnimationOptions) UIViewAnimationCurveEaseInOut animations:^{
[self setupAnimation];
} completion:nil];
}
- (void) cancelView {
[UIView animateWithDuration:0.35 delay:0 options:UIViewAnimationCurveEaseInOut animations:^{
self.cancelButton.frame = CGRectMake (self.frameForCancelButton.origin.x, self.frameForCancelButton.origin.y + kAnimationOffset, self.frameForCancelButton.size.width, self.frameForCancelButton.size.height);
self.collectionView.frame= CGRectMake(self.frameForCollectionView.origin.x, self.frameForCollectionView.origin.y + kAnimationOffset, self.frameForCollectionView.size.width, self.frameForCollectionView.size.height);
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
;
}
- (void) setupAnimation {
self.cancelButton.alpha = 1;
self.collectionView.alpha = 1;
self.cancelButton.frame = self.frameForCancelButton;
self.collectionView.frame = self.frameForCollectionView;
[self addShapeLayer];
}
- (void)addShapeLayer
{
self.shapeLayer = [CAShapeLayer layer];
self.shapeLayer.path = [[self pathAtInterval:0.0] CGPath];
self.shapeLayer.fillColor = [[UIColor redColor] CGColor];
self.shapeLayer.lineWidth = 3.0;
self.shapeLayer.strokeColor = [[UIColor redColor] CGColor];
[self.collectionView.layer insertSublayer:self.shapeLayer atIndex:0];
}
- (UIBezierPath *) pathAtInterval:(NSTimeInterval) interval {
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(self.collectionView.frame.origin.x,self.collectionView.frame.origin.y)];
[path addQuadCurveToPoint:CGPointMake(self.collectionView.frame.size.width, self.collectionView.frame.origin.y) controlPoint:CGPointMake(self.collectionView.frame.size.width/2, self.collectionView.frame.origin.y-30)];
return path;
}
Your animation block does not contain any animations. You should move your setup outside of the animation block and then animate within it.
[self setupAnimation];
[UIView animateWithDuration:1.0 delay:0.45 options:(UIViewAnimationOptions) UIViewAnimationCurveEaseInOut animations:^{
// animate something
} completion:nil];
In addition to this, your intended animation does not have a linear progression, meaning that you'l want to use animateKeyframesWithDuration instead.
[UIView animateKeyframesWithDuration:1.0 delay:0.45 options:UIViewAnimationCurveEaseInOut animations:^{
for (NSInteger i = 0; i < 10; i++) {
[UIView addKeyframeWithRelativeStartTime:i/10.0
relativeDuration:1.0/10.0
animations:^{
self.shapeLayer = [self pathAtInterval:i/10.0];
}];
}
} completion:nil];
1, add the path you created to CAShaperLayer object;
2, see the "strokeStart" and "strokeEnd" properties in CAShapeLayer class;
3, add a animation which called "CABasicAnimation" to your Layer obj.

UIViewAnimationWithDuration not respecting the duration?

Alright, I'm almost positive I'm just doing something stupid, but I'm new to this, so please excuse my incompetence. I have a nested animation block, and it changes the view controller once it's finished - one problem. It fires prematurely. I don't know if it's me incorrectly changing the view controller, or the block is incorrect. Any help would be great. Thanks in advance.
SplashViewController.m
#import "SplashViewController.h"
#import "MenuViewController.h"
#interface SplashViewController ()
#end
#implementation SplashViewController
-(void) drawColoredBars
{
UIView *greenBar = [[UIView alloc] initWithFrame:CGRectMake(75.0, -self.view.bounds.size.height, 3.0, self.view.bounds.size.height)];
UIView *orangeBar = [[UIView alloc] initWithFrame:CGRectMake(87.5, -self.view.bounds.size.height - 25, 3.0, self.view.bounds.size.height)];
UIView *yellowBar = [[UIView alloc] initWithFrame:CGRectMake(100.0, -self.view.bounds.size.height - 50, 3.0, self.view.bounds.size.height)];
UIColor *green = [UIColor colorWithRed:142.0/255.0f green:149.0/255.0f blue:31.0/255.0f alpha:0.6f];
UIColor *orange = [UIColor colorWithRed:204.0/255.0f green:82.0/255.0f blue:29.0/255.0f alpha:0.6f];
UIColor *yellow = [UIColor colorWithRed:254.0/255.0f green:190.0/255.0f blue:16.0/255.0f alpha:0.6f];
greenBar.backgroundColor = green;
orangeBar.backgroundColor = orange;
yellowBar.backgroundColor = yellow;
greenBar.tag = 1;
orangeBar.tag = 2;
yellowBar.tag = 3;
[self.view addSubview:greenBar];
[self.view addSubview:orangeBar];
[self.view addSubview:yellowBar];
}
-(void) animate
{
MenuViewController *menu = [[MenuViewController alloc] init];
double delay = 0.0;
double x = 75.0;
for (int i = 1; i < 4; i++) {
CGRect frame = CGRectMake(x, 0.0, 3.0, self.view.bounds.size.height);
[UIView animateWithDuration: 2.5
delay: delay
options: UIViewAnimationOptionCurveEaseIn
animations:^{
[self.view viewWithTag:i].frame = frame;
}
completion:^(BOOL finished){
[UIView animateWithDuration: 2.5
delay: 2.5
options: UIViewAnimationOptionCurveEaseIn
animations:^{
self.view.alpha = 0.0;
}
completion:^(BOOL finished){
[self presentViewController:menu animated:NO completion:nil];
}];
}];
delay = delay + 0.5;
x = x + 12.5;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
CAGradientLayer *layer = [GradientBackground drawGradient];
layer.frame = self.view.bounds;
[self.view.layer insertSublayer:layer atIndex:0];
[self drawColoredBars];
[self animate];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
Once again, thanks!
The viewDidLoad method is too early to set up animations. Try putting [self animate] in viewDidAppear: instead.
Also, make sure [self.view viewWithTag:i] doesn't return nil. If it returns nil, the outer animation block doesn't have anything to animate and will fire its completion block immediately.

How can i show a message pop up like Play Music app

I want to add bar like Play Music app of google shows in the their application. I want to use that same animation effect as they are doing. So Can any one guide me that is there any open source code to add this functionality in the app or i need to code it all manually, any guide will be helpful, I search net but i did not found any.
#interface ViewController ()
#property (nonatomic, weak) UILabel *popupLabel;
#end
#implementation ViewController
- (UILabel *)popupLabel
{
if( !_popupLabel ) {
CGFloat height = 44.0;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,
self.view.bounds.size.height - height,
self.view.bounds.size.width,
height)];
label.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.5];
label.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor whiteColor];
label.alpha = 0.0;
[self.view addSubview:label];
_popupLabel = label;
}
[self.view bringSubviewToFront:_popupLabel];
return _popupLabel;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self performSelector:#selector(showWithMessage:) withObject:#"1 song added to playlist" afterDelay:2.0];
}
- (void)showWithMessage:(NSString *)message
{
self.popupLabel.text = message;
[UIView animateWithDuration:1.0 animations:^{
self.popupLabel.alpha = 1.0;
}];
}
- (void)hide
{
[UIView animateWithDuration:1.0 animations:^{
self.popupLabel.alpha = 0.0;
}];
}

Resources