Pull to refresh

iOS SDK — CoreAnimation, программируем красивые кнопки

Reading time 3 min
Views 5.1K
Многие наверняка сталкивались с необходимостью быстрого создания контролов в мобильном пользовательском интерфейсе. Рассмотрим стандартные кнопки UIButton. Базовый контрол мало устраивает взыскательного заказчика и зачастую стандартное решение, это натягивание на кнопки битмапов состояния. Растянутая ли это картинка или целиком вырезаная кнопка — решение требует дополнительных временных затрат на дизайн пользовательского интерфейса. Хорошо было бы иметь универсальный контрол, с более широкими визуальными возможностями, чем базовый UIButton.


Самым логичным представляется экстендить UIButton — так и сделаем
создаем свой класс наследованный от UIButton (не забываем включить в проект QuartzCore.framework), он нам очень облегчит совместную жизнь с визулкой в iOS.

@class CAGradientLayer;

@interface CustomButton : UIButton {
@private
UIColor* _gradientStartColor;
UIColor* _gradientEndColor;

CAGradientLayer* _gradientLayer;
}

@property (nonatomic, retain) UIColor* gradientStartColor;
@property (nonatomic, retain) UIColor* gradientEndColor;

@end


Как многие догадались, мы будем использовать CAGradientLayer для отрисовки градиентного фона кнопки. Этот класс предоставляет широкие возможности заливки. Мы рассмотрим лишь малую (базовую) их часть.

#import "CustomButton.h"
#import <QuartzCore/QuartzCore.h>

@implementation CustomButton

@synthesize gradientStartColor = _gradientStartColor;
@synthesize gradientEndColor = _gradientEndColor;


коль скоро мы планируем использовать наш контрол в InterfaceBuilder (далее IB), инициализация должна происходить в методе ниже

-(void)awakeFromNib;
{
_gradientLayer = [[CAGradientLayer alloc] init];
_gradientLayer.bounds = self.bounds;

_gradientLayer.position = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);

[self.layer insertSublayer:_gradientLayer atIndex:0];

self.layer.cornerRadius = 5.0f; // пусть будет хардкод, для теста
self.layer.masksToBounds = YES;
self.layer.borderWidth = 1.0f;

}


отрисовочка градиентного слоя

- (void)drawRect:(CGRect)rect;
{
if (_gradientStartColor && _gradientEndColor)
{
[_gradientLayer setColors:
[NSArray arrayWithObjects: (id)[_gradientStartColor CGColor]
, (id)[_gradientEndColor CGColor], nil]];
}

[super drawRect:rect];
}


мы ничего не забыли?

- (void)dealloc {
[_gradientEndColor release];
[_gradientStartColor release];
[_gradientLayer release];
[super dealloc];
}

@end


вот наш маленький классец и заиплеменчен, давайте попробуем вставить его в интерфейс.

Создаем в контроллере вида аутлет типа нашего класса (CustomButton)

@interface GlossyButtonTestViewController : UIViewController {
@private
IBOutlet CustomButton* btn;
}


Открываем IB, всавляем кнопку с типом Custom и связываем ее с аутлетом в контроллере.
В теле имплементации контроллера дописываем инициализауию значений цветов градиента фона кнопки.

- (void)viewDidLoad {
[super viewDidLoad];

btn.gradientStartColor = [UIColor whiteColor];
btn.gradientEndColor = [UIColor grayColor];
[self.view addSubview:btn];
}


собираем проект и видим
вот такую кнопку



Вполне себе кнопка и можно было бы ограничиться, но мы пойдем дальше. Тут явно не хватает блеска.

Сказано сделано — добавляем блик на кнопку.

В интерфейс вставляем еще один слой и добавляем в awakeFromNib его инициализацию

_glossyLayer = [[CAGradientLayer alloc] init];
_glossyLayer.bounds = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height/2);
_glossyLayer.position = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/4);
[self.layer addSublayer:_glossyLayer];


в drawRect дописываем инициализацию цветов градиента слоя


[_glossyLayer setColors:
[NSArray arrayWithObjects:
(id)[[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:0.99f] CGColor]
, (id)[[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:0.2f] CGColor], nil]];


и… запускаем
Вот и все.



Не забываем, что слою CoreAnimation можно добавить транзакции переходов и т.п.
Наш класс носит исключительно познавательный характер, для полноценного использования в проектах его необходимо расширить анимациями состояний.

Автор поста Marshet15, но у него недостаточно кармы для публикации статьи.
Tags:
Hubs:
+17
Comments 35
Comments Comments 35

Articles