城市選擇器

来源:http://www.cnblogs.com/YouXianMing/archive/2017/09/12/7510986.html
-Advertisement-
Play Games

效果 源碼 https://github.com/YouXianMing/Animations 特點 1. 每一個row都可以像使用UITableView的cell一樣可以定製,繼承CustomPickerView即可 2. 數據源通過PickerViewDataAdapter來指定,每一個Pick ...


效果

 

源碼

https://github.com/YouXianMing/Animations

//
//  CustomCityPickerViewController.m
//  Animations
//
//  Created by YouXianMing on 2017/9/12.
//  Copyright © 2017年 YouXianMing. All rights reserved.
//

#import "CustomCityPickerViewController.h"
#import "PickerCityDataManager.h"
#import "FileManager.h"
#import "NSData+JSONData.h"
#import "CustomPickerView.h"
#import "PickerViewDataAdapter.h"
#import "UIView+SetRect.h"
#import "PickerProvinceView.h"
#import "PickerCityView.h"
#import "PickerAreaView.h"

@interface CustomCityPickerViewController () <CustomPickerViewDelegate>

@property (nonatomic, strong) NSArray <PickerProvinceModel *> *provinces;

@property (nonatomic, strong) CustomPickerView      *pickerView;
@property (nonatomic, strong) PickerViewDataAdapter *pickerViewDataAdapter;

@end

@implementation CustomCityPickerViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];

    // Get data.
    NSData  *data      = [NSData dataWithContentsOfFile:[FileManager bundleFileWithName:@"city.json"]];
    NSArray *provinces = [data toListProperty];
    self.provinces     = [PickerCityDataManager provinceModelsWithArray:provinces];
    
    // Create CustomPickerView's dataAdapter.
    self.pickerViewDataAdapter = [PickerViewDataAdapter pickerViewDataAdapterWithComponentsBlock:^(NSMutableArray<PickerViewComponent *> *components) {
        
        // Province component.
        PickerViewComponent *provinceComponent = [PickerViewComponent pickerViewComponentWithRowsBlock:^(NSMutableArray<PickerViewRow *> *rows) {
            
            [self.provinces enumerateObjectsUsingBlock:^(PickerProvinceModel *provinceModel, NSUInteger idx, BOOL * _Nonnull stop) {
                
                [rows addObject:[PickerViewRow pickerViewRowWithViewClass:[PickerProvinceView class] data:provinceModel]];
            }];
            
        } componentWidth:Width / 3.f - 5.f];
        
        // City component.
        PickerViewComponent *cityComponent = [PickerViewComponent pickerViewComponentWithRowsBlock:^(NSMutableArray<PickerViewRow *> *rows) {
            
            [self.provinces.firstObject.cities enumerateObjectsUsingBlock:^(PickerCityModel *cityModel, NSUInteger idx, BOOL * _Nonnull stop) {
                
                [rows addObject:[PickerViewRow pickerViewRowWithViewClass:[PickerCityView class] data:cityModel]];
            }];
            
        } componentWidth:Width / 3.f - 5.f];
        
        // Area component.
        PickerViewComponent *areaComponent = [PickerViewComponent pickerViewComponentWithRowsBlock:^(NSMutableArray<PickerViewRow *> *rows) {
            
            [self.provinces.firstObject.cities.firstObject.areas enumerateObjectsUsingBlock:^(PickerAreaModel *areaModel, NSUInteger idx, BOOL * _Nonnull stop) {
                
                [rows addObject:[PickerViewRow pickerViewRowWithViewClass:[PickerAreaView class] data:areaModel]];
            }];
            
        } componentWidth:Width / 3.f - 5.f];
        
        [components addObject:provinceComponent];
        [components addObject:cityComponent];
        [components addObject:areaComponent];
        
    } rowHeight:60.f];
    
    // Create CustomPickerView.
    self.pickerView = [[CustomPickerView alloc] initWithFrame:CGRectMake(0, 0, Width, 0)
                                                     delegate:self
                                         pickerViewHeightType:kCustomPickerViewHeightTypeMax
                                                  dataAdapter:self.pickerViewDataAdapter];
    self.pickerView.center = self.contentView.middlePoint;
    [self.contentView addSubview:self.pickerView];
}

#pragma mark - CustomPickerViewDelegate

- (void)customPickerView:(CustomPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    
    if (component == 0) {
        
        NSMutableArray *citys = [NSMutableArray array];
        [self.provinces[row].cities enumerateObjectsUsingBlock:^(PickerCityModel *cityModel, NSUInteger idx, BOOL * _Nonnull stop) {
            
            [citys addObject:[PickerViewRow pickerViewRowWithViewClass:[PickerCityView class] data:cityModel]];
        }];
        
        NSMutableArray *areas = [NSMutableArray array];
        [self.provinces[row].cities.firstObject.areas enumerateObjectsUsingBlock:^(PickerAreaModel *areaModel, NSUInteger idx, BOOL * _Nonnull stop) {
            
            [areas addObject:[PickerViewRow pickerViewRowWithViewClass:[PickerAreaView class] data:areaModel]];
        }];
        
        pickerView.pickerViewDataAdapter.components[1].rows = citys;
        pickerView.pickerViewDataAdapter.components[2].rows = areas;
        [pickerView reloadComponent:1];
        [pickerView reloadComponent:2];
        [pickerView selectRow:0 inComponent:1 animated:YES];
        [pickerView selectRow:0 inComponent:2 animated:YES];
        
    } else if (component == 1) {
        
        NSInteger       provinceIndex = [self.pickerView selectedRowInComponent:0];
        NSMutableArray *areas         = [NSMutableArray array];
        
        // Protect crash.
        if (self.provinces[provinceIndex].cities.count <= row) {
            
            row = self.provinces[provinceIndex].cities.count - 1;
        }
        
        [self.provinces[provinceIndex].cities[row].areas enumerateObjectsUsingBlock:^(PickerAreaModel *areaModel, NSUInteger idx, BOOL * _Nonnull stop) {
            
            [areas addObject:[PickerViewRow pickerViewRowWithViewClass:[PickerAreaView class] data:areaModel]];
        }];
        
        pickerView.pickerViewDataAdapter.components[2].rows = areas;
        [pickerView reloadComponent:2];
        [pickerView selectRow:0 inComponent:2 animated:YES];
    }
}

- (void)customPickerView:(CustomPickerView *)pickerView didSelectedRows:(NSArray <NSNumber *> *)rows selectedDatas:(NSArray <id> *)datas {
    
    NSLog(@"%@", datas);
}

@end

 

特點

1. 每一個row都可以像使用UITableView的cell一樣可以定製,繼承CustomPickerView即可

2. 數據源通過PickerViewDataAdapter來指定,每一個PickerViewComponent都有一個PickViewRow的數組,每一個PickViewRow元素都對應一個自定義的CustomPickerView。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 上篇博文【 Js利用Canvas實現圖片壓縮 】中做了圖片壓縮上傳,但是在IOS真機測試的時候,發現圖片預覽的時候自動逆時針旋轉了90度。對於這個bug,我完全不知道問題出在哪裡,接下來就是面向百度編程了。通過度娘找到了相關資料,解決方法記錄在此。這個問題的具體因素其實我還是不清楚是為何導致的,只有 ...
  • 從廣義上來講,css3動畫可以分為兩種。 過渡動畫 第一種叫過渡(transition)動畫,就是從初始狀態過渡到結束狀態這個過程中所產生的動畫。所謂的狀態就是指大小、位置、顏色、變形(transform)等等這些屬性。css過渡只能定義首和尾兩個狀態,所以是最簡單的一種動畫。要想使一個元素產生過渡 ...
  • 程式的流程圖: 主要代碼: 服務端 app.js 先載入所需要的通信模塊: 創建用戶列表和消息列表: 綁定並監聽80埠: 客戶端連接成功後,觸發響應事件connection,完成要綁定的事件並實現客戶端出發的事件: 客戶端 index.js: 先初始化用戶信息: 然後連接伺服器端: 連接成功後,對 ...
  • 一般 直接new Date() 是不會出現相容性問題的,而 new Date(datetimeformatstring) 常常會出現瀏覽器相容性問題,為什麼,datetimeformatstring中的某些格式瀏覽器不相容。 1. 無參 a. IE > IE9-(不相容) > IE9+(相容,包含I ...
  • xml <?xml version="1.0" encoding="utf-8"?><android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:too ...
  • 封面預覽 前言 使用百度貼吧客戶端的時候發發現載入的小動畫挺有意思的,於是自己動手寫寫看。想學習自定義View以及自定義動畫的小伙伴一定不要錯過哦。 讀者朋友需要有最基本的canvas繪圖功底,比如畫筆Paint的簡單使用、Path如何畫直線等簡單的操作,不熟悉也沒關係,下文帶大家擼代碼的時候會簡單 ...
  • 數組的介紹 數組的介紹 數組(Array)是一串有序的由相同類型元素構成的集合,數組中的集合元素是有序的,可以重覆出現。在Swift中數組類型是Array,是一個泛型集合。數組分成:可變數組和不可變數組,分別使用let修飾的數組是不可變數組,使用var修飾的數組是可變數組。 數組的初始化 數組的初始 ...
  • 5種android對話框1 彈出普通對話框 系統更新2 自定義對話框-- 用戶登錄3 時間選擇對話框 -- 時間對話框4 進度條對話框 -- 信息載入..5 popuWindow對話框 1 彈出普通對話框 系統更新 [csharp] view plain copy //彈出普通對話框 public  ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...