iOS開發(fā)位移枚舉NS_OPTIONS的使用,以星期為例

1.前言

在iOS開發(fā)中旱爆,枚舉值是大家用得比較多的,但是大家一般常用的是NS_ENUM/enum,對于NS_OPTIONS大家用得可能比較少窘茁,因為NS_ENUM就能解決大部分問題怀伦,不過如果學(xué)會了NS_OPTIONS的使用,在開發(fā)中會如虎添翼山林。

2.NS_ENUM和NS_OPTIONS

既然NS_ENUM和NS_OPTIONS都是代表枚舉值房待,那么他們到底有什么區(qū)別呢?在開發(fā)中驼抹,怎么選擇使用哪一個呢桑孩?
先來簡單的說說區(qū)別:NS_ENUM通常來說,只能選擇一個值砂蔽,而NS_OPTIONS由于是位移枚舉洼怔,可以進(jìn)行計算署惯,所以NS_OPTIONS通匙蠹荩可以選擇多個值。從他們的區(qū)別可以看出來极谊,我們在開發(fā)中诡右,如果是需要使用固定的值,而且只會有一種狀態(tài)轻猖,比如網(wǎng)絡(luò)請求帆吻,要么是200,要么是400咙边,要么是500等等猜煮,不可能出現(xiàn)既是200的情況又是400的情況次员,在這種只有一個取值的情況下,選擇NS_ENUM就好了王带,而對于一個狀態(tài)可以有多個取值的淑蔚,比如如果給按鈕設(shè)置圓角,那么有上下左右4個方向愕撰,而你可以只設(shè)置左邊有圓角刹衫,也可以設(shè)置左邊和右邊有圓角,這樣就有很多種排列組合搞挣。
所以带迟,綜上來說,對于只有一種取值情況的囱桨,用NS_ENUM就可以仓犬,對于可以有多種情況的,用NS_OPTIONS最簡單蝇摸。
本文會以星期的選擇為例子婶肩,來詳細(xì)講解NS_OPTIONS,通過這個例子貌夕,大家可以知道在開發(fā)中律歼,怎么去定義,怎么使用啡专,怎么取消選中险毁,怎么拿到值了進(jìn)行選中。但是里面會涉及一些編碼们童,補(bǔ)碼畔况,反碼的知識,本文就不詳細(xì)的講解了慧库,大家感興趣的可以詳細(xì)的去查找一下資料(主要是由于年代久遠(yuǎn)跷跪,當(dāng)初學(xué)習(xí)的數(shù)字電路知識大部分忘記了,只知道怎么使用齐板,忘記原理了:((()吵瞻。

3.NS_OPTIONS的定義

//星期選擇
typedef NS_OPTIONS(NSInteger, ALWeekRepeat) {
    ALWeekRepeatNone      = 0,//未選擇
    ALWeekRepeatMonday    = 1<<1,
    ALWeekRepeatTuesday   = 1<<2,
    ALWeekRepeatWednesday = 1<<3,
    ALWeekRepeatThursday  = 1<<4,
    ALWeekRepeatFriday    = 1<<5,
    ALWeekRepeatSaturday  = 1<<6,
    ALWeekRepeatSunday    = 1<<7
};

位置圖示

從定義可以看出,就是讓每一位代表一個值甘磨。簡單來說,NS_OPTIONS換算下來也是普通的值橡羞,比如第一位,換算下來定義的就是1济舆,第二位換算下來就是2卿泽,第三位是4。有人可能有疑惑滋觉,既然換算下來是這樣的值签夭,那么我定義得時候用NS_ENUM定義成1齐邦,2,3第租,4侄旬,然后進(jìn)行或運算不更簡單嗎?但你仔細(xì)算一下你會發(fā)現(xiàn)煌妈,有些兩個值組合會等于另一個單獨定義得值儡羔,你會分不清這個值到底是代表我定義得值,還是說這個值是單獨定義的值璧诵。打個比方汰蜘,假如你1 | 2 = 3,那么你就分不清楚這個得出的結(jié)果到底是我單獨定義的3呢之宿,還是兩個1|2的計算結(jié)果族操。所以用NS_OPTIONS來進(jìn)行定義,保證每一位只代表一個值比被,兩個值進(jìn)行或計算就是一個獨一無二的值色难,不會出現(xiàn)這種沖突的情況,而起因為有左移運算<<等缀,你不需要具體的去計算哪一位的值是多少枷莉,只需要進(jìn)行定義下去就行。

4.NS_OPTIONS的多個選擇與取消選擇

    NSArray *weekarray = @[@"M",@"TU",@"W",@"TH",@"F",@"SA",@"SU"];
    CGFloat weekButtonWidth = 30;
    CGFloat margin = (self.view.frame.size.width - weekButtonWidth * 7) / 8;
    for (NSInteger i = 0; i < weekarray.count; i++) {
        UIButton *weekBtn = [[UIButton alloc]init];
        weekBtn.tag = i;
        weekBtn.frame = CGRectMake( margin + i * (margin + weekButtonWidth), 100, weekButtonWidth, weekButtonWidth);
        [weekBtn setTitle:weekarray[i] forState:UIControlStateNormal];
        [weekBtn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [weekBtn setTitleColor:RGB(33, 209, 102) forState:UIControlStateSelected];
        weekBtn.adjustsImageWhenHighlighted = NO;
        [weekBtn addTarget:self action:@selector(weekBtnClick:) forControlEvents:UIControlEventTouchUpInside];
        
        [self.view addSubview:weekBtn];
    }
星期按鈕

上圖是一個簡單的定義星期的UI尺迂。建議大家排列順序和你的定義的枚舉值進(jìn)行一一對應(yīng)笤妙,比如你第一位定義的是星期一,那么你的按鈕就從星期一開始噪裕,這樣方便后面的選擇計算蹲盘。
對于選中,這個比較簡單膳音,進(jìn)行或運算即可召衔,如果用戶取消了,由于&是與|相對的祭陷,只需要進(jìn)行&即可苍凛,但是,記得一定要取反才行(具體原理忘記了颗胡,反正就是那些反碼相關(guān)的知識)毫深。按鈕點擊的方法如下:

-(void)weekBtnClick:(UIButton *)button{
    button.selected = !(button.selected);
    if (button.isSelected) {
        _tempWeekRepeat |= 1<<(button.tag +1);
        button.backgroundColor = RGB(242, 242, 242);
        button.layer.cornerRadius = 15;
        button.layer.masksToBounds = YES;
    }else{
        _tempWeekRepeat &= ~(1<<(button.tag +1));
        button.backgroundColor = [UIColor whiteColor];
        button.layer.cornerRadius = 0;
    }
}

_tempWeekRepeat是一個定義的全局變量吩坝,用來記錄這次用戶的點擊與取消點擊毒姨。

5.通過枚舉值設(shè)置按鈕的選中狀態(tài)

經(jīng)驗老到的后臺,基本都會知道位運算钉寝,這時候他就會要求你傳選中狀態(tài)的計算值給到他弧呐,比如選擇了星期一和星期三闸迷,那么計算出來的值是5,后臺也就只需要5俘枫,他就知道用戶選擇了星期幾腥沽。當(dāng)你去get下載下來的值,也是這個值鸠蚪,這時候今阳,要怎樣在用戶的界面顯示出來呢,其實也很簡單茅信,只需要在創(chuàng)建按鈕for循環(huán)的時候判斷一下即可盾舌。

if ((_tempWeekRepeat & (1<<(i+1)))) {
            weekBtn.selected = YES;
            weekBtn.backgroundColor = RGB(242, 242, 242);
        }

這樣就能知道5的意思是選中了星期一和星期三。
當(dāng)然了如果你們后臺是要求傳一些奇葩的值蘸鲸,比如[0,0,0,0,1,0,1]代表星期一和星期三選中妖谴。那么你就需要自己和他溝通,叫他學(xué)習(xí)一下位移枚舉酌摇,或者是你自己解決了膝舅。

6.結(jié)語

位移枚舉NS_OPTIONS對于這種有多個狀態(tài)的情況,是相當(dāng)?shù)挠押靡ざ啵疫@里基本把開發(fā)中常用的選中與取消選中仍稀,以及服務(wù)器上的值怎么讓按鈕選中進(jìn)行了演示,如果你需要開發(fā)中使用完全沒問題埂息,但是如果你想知道具體實現(xiàn)的原理琳轿,你就需要去查詢一下相關(guān)的編碼、補(bǔ)碼耿芹、反碼的知識了崭篡。
可能本文講解的不是很詳細(xì),所以demo附上吧秕,供各位參考琉闪,你只需要用一下demo,就會知道具體的使用:https://github.com/CHNDarryl/OptionDemo
另外砸彬,代碼也不多颠毙,在附一張代碼截圖:

代碼截圖

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市砂碉,隨后出現(xiàn)的幾起案子蛀蜜,更是在濱河造成了極大的恐慌,老刑警劉巖增蹭,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滴某,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)霎奢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門户誓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人幕侠,你說我怎么就攤上這事帝美。” “怎么了晤硕?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵悼潭,是天一觀的道長。 經(jīng)常有香客問我舞箍,道長女责,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任创译,我火速辦了婚禮抵知,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘软族。我一直安慰自己刷喜,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布立砸。 她就那樣靜靜地躺著掖疮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪颗祝。 梳的紋絲不亂的頭發(fā)上浊闪,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機(jī)與錄音螺戳,去河邊找鬼搁宾。 笑死,一個胖子當(dāng)著我的面吹牛倔幼,可吹牛的內(nèi)容都是我干的盖腿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼损同,長吁一口氣:“原來是場噩夢啊……” “哼翩腐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起膏燃,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤茂卦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后组哩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體等龙,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡处渣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了而咆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡幕袱,死狀恐怖暴备,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情们豌,我是刑警寧澤涯捻,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站望迎,受9級特大地震影響障癌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜辩尊,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一涛浙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧摄欲,春花似錦轿亮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至迟隅,卻和暖如春但骨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背智袭。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工奔缠, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吼野。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓添坊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親箫锤。 傳聞我的和親對象是個殘疾皇子贬蛙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容