城市選擇器

来源: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
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...