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,这样天气预报的主要流程就结束了。

猜你喜欢

转载自blog.csdn.net/qq_42347755/article/details/81835264