1. 程式人生 > >Objective-C天氣預報總結

Objective-C天氣預報總結

  1. 暑假留校的最後一個任務是寫個能聯網的天氣預報,首先附上github地址:天氣預報。雖說從開始寫到結束只有短短四天但中間也碰到了一些問題我覺得有必要總結一下。
  2. 首先的問題是天氣預報框架的構造,在參照手機自帶天氣預報app後,決定將中間選擇城市頁面作為首頁,在新增城市的同時該介面同步新增選擇城市,tableView的cell設定為儲存城市的陣列個數就輕鬆搞定,在首頁介面協議傳值的函式請求介面資料並在請求資料的塊中重新整理tableView即可。
  3. 然後到了新增城市的介面即搜尋介面,參照手機app上的功能,它有輸入時自動檢索功能,這個的實現對我來說還是第一次接觸,再上網搜尋資料後學習了searchController控制元件,在它的
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController{


}

協議函式中將搜尋欄中的輸入框的文字賦給一個臨時字串變數,然後將該字串作為請求介面的地址引數賦值,同時,在每請求一次資料的同時重新整理一次tableView就可以實現自動檢索功能。對了,在跳轉頁面的時候遇到了一個小問題,在選中城市dismiss回首頁介面時,當文字框處於輸入狀態時,需要將

[self dismissViewControllerAnimated:YES completion:nil];

語句執行兩次才能返回首頁介面,研究後是和searchController有關,第一次dismiss會退出編輯狀態,但具體原因還不太清楚。
4. 回到首頁頁面,通過協議傳值將儲存要請求天氣的城市的陣列傳遞過來,並在協議函式中通過post請求請求資料賦給tableView,這樣首頁的選擇介面也就完成了。
5. 最後到了顯示天氣的主介面,這裡相對來說是最麻煩的,在這裡,需求中要求要實現新增多個城市時可以左右滑動主介面來看不同城市的天氣,我的實現方法是貼一張大的scrollView放在檢視控制器上,然後自定義view來放置tableView。但在剛開始放置時遇到了點小問題,在一個cell上要看當天24小時逐時天氣,通過scrollView來實現。由於數量很多,於是我又寫了個自定義view放每個小時的內容,通過for迴圈來建立賦值,後來學姐提醒我建立和賦值不能同時放在判斷複用池為空的程式碼塊裡,這樣如果要實現重新整理實時天氣的需求就無法實現了,但我又不知道賦值操作放在程式碼塊外如何訪問到內部建立的view,這裡學到一個小技巧,現將更正後程式碼附上:

else if(indexPath.section == 1){
        UITableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:@"cell1"];
        if(cell1 == nil){
            cell1 = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell1"];
            scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 414, 153)];
            scrollView.contentSize = CGSizeMake(90*24, 0);
            scrollView.bounces = NO;
            scrollView.backgroundColor = [UIColor clearColor];
            cell1.backgroundColor = [UIColor clearColor];
            cell1.contentView.backgroundColor = [UIColor clearColor];
            for (int i = 0; i < 24; i++) {
                Weather *weatherView = [[Weather alloc] initWithFrame:CGRectMake(90*i, 0, 90, 153)];
                weatherView.tag = i;
                [scrollView addSubview:weatherView];
            }
            [cell1.contentView addSubview:scrollView];
        }
        if (scrollViewModel != YES) {
            return cell1;
        }
        int i = 0;
        for (Weather *weatherView in [scrollView subviews]) {
            if (i > 23) {
                break;
            }
            weatherView.label.text = self.timeArray[weatherView.tag];
            UIImage *image = [UIImage imageNamed:self.weatherArray[weatherView.tag]];
            weatherView.imageView.image = image;
            weatherView.label1.text = self.tmpArray[weatherView.tag];
            i++;
        }
        return cell1;
    }
  1. 最後在我寫完之後,有一個小困惑,就是由於網路請求的資料由於執行緒的問題,如果將tableVIew放在initWithFrame的函式塊中,會先對tableView的內容進行賦值,這時候因為請求的資料還沒有得到,所以程式會崩潰。後我將建立tableView放在請求完資料的程式碼塊中,程式就可以正常運行了,但因為我請求了兩個介面,經過嘗試我只有把tableView放在其中一箇中才能正常執行,詢問原因後得知是因為介面請求速度但原因,照理說兩個介面請求到資料的先後順序是隨機的,但因為這兩個網站的原因,永遠一個快一個慢,所以我的程式沒有出現崩潰,但理論上來說我的程式碼是有問題的。解決方案是,給tableView增加兩個BOOL型別的成員變數,在賦值請求成功後賦給yes值,然後在tableView賦值時進行判斷,如果不為yes,直接return cell的值,否則進行賦值操作,然後在每個請求資料完成後呼叫重新後的tableView的get方法進行建立(self.和_呼叫物件的一個區別就是self.會呼叫該物件的get方法,而下劃線不會),並重新整理tableView,這樣天氣預報的主要流程就結束了。