Я создал помощника в UIView
@interface UIView (Helper)
- (void)roundCornerswithRadius:(float)cornerRadius
andShadowOffset:(float)shadowOffset;
@end
, вы можете называть его так
[self.view roundCornerswithRadius:5 andShadowOffset:5];
Вот реализация
- (void)roundCornerswithRadius:(float)cornerRadius
andShadowOffset:(float)shadowOffset
{
const float CORNER_RADIUS = cornerRadius;
const float SHADOW_OFFSET = shadowOffset;
const float SHADOW_OPACITY = 0.5;
const float SHADOW_RADIUS = 3.0;
UIView *superView = self.superview;
CGRect oldBackgroundFrame = self.frame;
[self removeFromSuperview];
CGRect frameForShadowView = CGRectMake(0, 0, oldBackgroundFrame.size.width, oldBackgroundFrame.size.height);
UIView *shadowView = [[UIView alloc] initWithFrame:frameForShadowView];
[shadowView.layer setShadowOpacity:SHADOW_OPACITY];
[shadowView.layer setShadowRadius:SHADOW_RADIUS];
[shadowView.layer setShadowOffset:CGSizeMake(SHADOW_OFFSET, SHADOW_OFFSET)];
[self.layer setCornerRadius:CORNER_RADIUS];
[self.layer setMasksToBounds:YES];
[shadowView addSubview:self];
[superView addSubview:shadowView];
}
Ваше перечисление должно быть степенями двойки:
enum
{
TAKES_DAMAGE = 1,
GRABBABLE = 2,
LIQUID = 4,
SOME_OTHER = 8
};
Или более читаемым способом:
enum
{
TAKES_DAMAGE = 1 << 0,
GRABBABLE = 1 << 1,
LIQUID = 1 << 2,
SOME_OTHER = 1 << 3
};
Почему? Потому что вы хотите иметь возможность комбинировать флаги без перекрытия, а также иметь возможность делать это:
if(myVar & GRABBABLE)
{
// grabbable code
}
... Что работает, если значения перечисления выглядят так:
TAKES_DAMAGE: 00000001
GRABBABLE: 00000010
LIQUID: 00000100
SOME_OTHER: 00001000
Итак, допустим, вы установили myVar
в GRABBABLE | TAKES_DAMAGE
, вот как это работает, когда вам нужно проверить флаг GRABBABLE:
myVar: 00000011
GRABBABLE: 00000010 [AND]
-------------------
00000010 // non-zero => converts to true
Если вы установите myVar
на LIQUID | SOME_OTHER
, операция привела бы к следующему:
myVar: 00001100
GRABBABLE: 00000010 [AND]
-------------------
00000000 // zero => converts to false
Другой способ хранения флагов - вообще не беспокоиться о базовом типе. при использовании перечисления значения перечисления по умолчанию сохраняются в целое число без знака, которое на обычном компьютере составляет 32 бита. это дает вам только 32 возможных флага: хотя, конечно, много, в некоторых случаях этого недостаточно.
теперь вы можете определить свой флаг следующим образом:
typedef struct
{
int takes_damage : 1;
int grabbable : 1;
int liquid : 1;
int some_other : 1;
} flags;
если вы никогда не сталкивались с этим, часть ': 1' сообщает компилятору использовать только 1 бит для хранения этого члена структуры.
теперь вы можете определить переменную для хранения флагов и работать с этими флагами:
flags myflags = {1,0,0,1}; // defines a variable holding a set of flags, with an initial value of takes_damage & some_other
myflags.liquid = 1; // change the flags to include the liquid
if ( myflags.takes_damage ) // test for one flag
apply_damage();
if ( myflags.liquid && myflags.some_other ) // test for multiple flags
show_strange_behavior();
этот метод позволяет вам определять любое количество флагов без ограничений, и вы можете расширить свой набор флагов в любое время, не опасаясь переполнение. недостатком является то, что тестирование подмножества флагов более громоздко и требует большего количества кода.
Да. Вместо этого сделайте члены перечисления степенями 2:
enum
{
TAKES_DAMAGE = (1 << 0),
GRABBABLE = (1 << 1),
LIQUID = (1 << 2),
SOME_OTHER = (1 << 3)
};
Вы должны сделать флаги только степенями двойки, то есть каждый из них является битом в любом типе данных, в котором вы его храните, и ничто не перекрывается при побитовом ИЛИ.
вам нужно
enum
{
TAKES_DAMAGE = 1,
GRABBABLE = 2,
LIQUID = 4,
SOME_OTHER = 8
};
Нельзя просто установить значения в enum?
enum {
TAKES_DAMAGE = 1,
GRABBABLE = 2,
LIQUID = 4
}
После этого просто выполните для них побитовое ИЛИ.