Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Программное управление размерами UIView - Objective-C

Войти
Регистрация
Восстановить пароль
Другие темы раздела
Objective-C Транформировать UIImage http://www.cyberforum.ru/objective-c/thread928338.html
Возможно ли с помощью метода CGContextConcatCTM трансформировать UIImage так, как на скриншоте? Если нет, то какой метод нужен для такой транформации?
Objective-C Как использовать dispatch_after? NSMutableString bufferAnswer; bool isBufferAnalysed; +(void) waitAnalys:(NSArray*) strInArray { isBufferAnalysed=false; NSMutableString *str; while (!isBufferAnalysed) {... http://www.cyberforum.ru/objective-c/thread927759.html
Литература по object c Objective-C
Подскажите хорошую литературу по 1) object c , 2) и с уклоном на ios разработку. Хочу начать изучать object c , но еще ничего не знаю, подскажите с чего начать, раскажите с чего начинали, чего...
Безопасность платного приложения Objective-C
Хочу поднять вопрос безопасности режимов работы платного приложения. В данном случае рассматривается приложение, которое осуществляются покупки через StoreKit Если скажем что сам api storekit...
Objective-C CoreData http://www.cyberforum.ru/objective-c/thread924468.html
Добрый день! У меня пара вопросов по CoreData. 1) Я правильно понимаю, что в атрибутах сущности должны находится объекты, которые не имеют подобъектов, а в отношениях должны находится объекты,...
Objective-C в чем отличия? Всем доброго времени суток. У меня вопросик возник пока изучаю Obj C в чем отличие такой записи от alert.show? Заранее спасибо за ответы подробнее

Показать сообщение отдельно
noname_club
103 / 94 / 10
Регистрация: 01.05.2013
Сообщений: 598

Программное управление размерами UIView - Objective-C

28.07.2013, 16:23. Просмотров 2533. Ответов 9
Метки (Все метки)

итак начнем с того, что нам предоставляет ObjC из коробки

[view setFrame:(CGRect) rect];

метод мгновенно установит параметры прямоугольника области view

и свойство view.frame

по нему можно прочесть параметры размера или записать через view.frame=rect новое значение

управление автоматическим выравниванием

Название: xrcT4.png
Просмотров: 444

Размер: 1.5 Кб

и тут все относительно просто

работаем через бинарное сложение флагов для установки нужного выравнивания

Objective-C
1
2
3
mySubview.autoresizingMask = (UIViewAutoresizingFlexibleWidth |    
                              UIViewAutoresizingFlexibleLeftMargin |  
                              UIViewAutoresizingFlexibleRightMargin);
---
казалось бы все достаточно просто, однако когда начинаешь с этим работать вплотную, то всплывают некоторые "недостатки" этих методов

1) размер

для размера используется СИ структура из 2 подстуктур
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct CGRect {
  CGPoint origin;
  CGSize size;
};
 
struct CGSize {
  CGFloat width;
  CGFloat height;
};
 
struct CGPoint {
  CGFloat x;
  CGFloat y;
};
это означает то, чтобы добраться скажем до ширины, нужно написать view.frame.size.width

то есть используем ветку size

все бы и неплохо, но когда требуется присвоить вот тут и начинаются "пляски"

конструкция view.frame.size.width = 4; не компилируется

для того чтобы присвоить, нужно выделить frame в отдельную область памяти, изменить его и !только! потом можно присвоить размер.

На практике это выглядит так

Objective-C
1
2
3
CGRect newframe = view.frame;
newframe.size.width = 4;
view.frame = newframe;
целых 2 лишних строки кода на простую манипуляцию размером.

поэтому для повышения чистоты кода нужно написать несколько дополнительных свойств к UIView

UIView+Sizing.h
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
@interface UIView (Sizing)
 
@property (nonatomic, assign) float height;
@property (nonatomic, assign) float width;
@property (nonatomic, assign) float posX;
@property (nonatomic, assign) float posY;
@property (nonatomic, readonly) float right;
@property (nonatomic, readonly) float bottom;
@property (nonatomic, assign) float top;
@property (nonatomic, assign) float left;
 
@end
после добавления категории в проект, управление размерами упрощается

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// изменяем координату x
 
view.posX = 12;
 
// считываем координату y
 
float y = view.posY;
 
// устанавливаем размер по ширине
 
view.with = 50;
 
// перемещение относительно Y вниз на 20px :D
 
view.posY += 20;
 
// << сравнение перегруженного кода
 
// обычный
view.frame = CGRectMake(view2.frame.origin.x+view3.origin.x, 150, view2.size.width, view2.size.height);
// через класс категорию
view.frame = CGRectMake(view2.posX+view3.posX, 150, view2.width, view2.height);
2) "эффект половинного пикселя"

эффект половинного пикселя связан с тем что размеры и координаты UIView являются дробными числами

теперь программно зададим дробную координату

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// первый
UILabel*lab = [[UILabel alloc] initWithFrame:CGRectMake(10.5f, 10.5f, 200, 40)];
    lab.text = @"Hello world";
    
    [lab setBackgroundColor:[UIColor blackColor]];
    
    [lab setFont:[UIFont fontWithName:@"Times New Roman" size:30]];
    [lab setTextColor:[UIColor whiteColor]];
    
    [self.view addSubview:lab];
 
 // второй
    UILabel* lab2 = [[UILabel alloc] initWithFrame:CGRectMake(10.0f, 10.0f+40, 200, 40)];
    lab2.text = @"Hello world";
    
    [lab2 setBackgroundColor:[UIColor blackColor]];
    
    [lab2 setFont:[UIFont fontWithName:@"Times New Roman" size:30]];
    [lab2 setTextColor:[UIColor whiteColor]];
    
    [self.view addSubview:lab2];
Программное управление размерами UIView
чтобы избежать его достаточно просто округлять координаты при присвоении.

или можно внести изменения в класс категорию, огородив таким образом размеры UIView от дробных чисел

UIView+Sizing.h
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
@interface UIView (Sizing)
 
@property (nonatomic, assign) int height;
@property (nonatomic, assign) int width;
@property (nonatomic, assign) int posX;
@property (nonatomic, assign) int posY;
@property (nonatomic, readonly) int right;
@property (nonatomic, readonly) int bottom;
@property (nonatomic, assign) int top;
@property (nonatomic, assign) int left;
 
@end

2) авторазмер

тут есть одна тонкость, которую сразу увидеть нельзя.

во первых угадайте какому состоянию авторазмера соответствует эта картинка?

Название: Снимок экрана 2013-07-28 в 2.46.22 PM.png
Просмотров: 440

Размер: 5.3 Кб

а вот эта

Название: Снимок экрана 2013-07-28 в 2.47.14 PM.png
Просмотров: 443

Размер: 5.3 Кб

ответы:

Кликните здесь для просмотра всего текста
1) UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight

2) UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin


удивлены? а все дело в том что полностью включенная картинка не означает, что должны использоваться все флаги

какая же картинка соответствует всем включенным флагам?

вот эта
Кликните здесь для просмотра всего текста
Название: Снимок экрана 2013-07-28 в 2.54.19 PM.png
Просмотров: 440

Размер: 5.3 Кб


вывод из этого такой что флаги _LeftMargin,_BottomMargin,_RightMargin,_TopMargin являются флагами инверсии по отношению к тому что изображено на картинке, то есть присутствие флага означает выключение

Это была теория, перейдем к практике

Возьмем самый безнадежный случай, когда нам надо включить все флаги.

view.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
код перегружен выражением UIViewAutoresizingFlexible

выход из ситуации? есть.

добавим в класс категорию метод установки маски через логические флаги вместо enum сложения

Objective-C
1
2
3
4
5
6
-(void) setAutoresizingMaskFlexibleTop:(bool) Top
                                  Left:(bool) Left
                                Bottom: (bool) Bottom
                                 Right:(bool) Right
                                 Width: (bool) Width
                                Height: (bool) Height;
теперь если нужно включить все флаги или один из них достаточно вызвать

Objective-C
1
[view setAutoresizingMaskFlexibleTop:YES Left:YES Bottom:YES Right:YES Width:YES Height:YES];
причем теперь не надо вспоминать эти самые флаги, поскольку эта функции их полностью заменяет.

Важно только помнить, что флаги положения имеют инверсию в отличие от флагов размера.
0
Вложения
Тип файла: zip test_position_user_manual.zip (41.1 Кб, 8 просмотров)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru