簡體   English   中英

iOS:如何在標簽欄控制器的不同視圖之間共享數據

[英]iOS: How to share data between different views of Tab Bar Controller

我的應用程序有兩個由標簽欄控制器管理的視圖。 其中一個視圖是Google Map(使用其SDK的GMSMapView),另一個是TableView,顯示相同數據的列表。 地圖上的標記是TableView中的相同數據(只是相同數據的替代表示)。

我從NSURLSessionDataTask獲取數據。 我想知道在兩個視圖之間共享該數據的最佳方法是什么。 顯然,我不想為每個視圖兩次提取數據。 但是我不確定使共享數據在兩個視圖之間可用/同步的最佳實踐是什么。

有人問過類似的問題,但在這里沒有回答。

您可以創建一個模型類,該模型類將與地圖相關的數據保存在一個數組/字典/自定義類對象中。 您可以將此模型類設為單例(只能初始化一次)。 現在,兩個視圖控制器(即地圖視圖和表格視圖)都可以引用此模型以在不同的視圖中填充日期。

Model Class
-----------

@property (strong, nonatomic) MyCustomDataRepresentationObj  *data;

+ (id)sharedModel {
    static MyModelClass *sharedModel = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedModel = [[self alloc] init];
    });
    return sharedModel;
}

-(void)fetchMapDataWithCompletionBlock:(void(^)(id response, NSError *error)onComplete
{
    // Check if data is available.
    // Note: You can add a refresh data method which will fetch data from remote servers again.
    if (!data) {
    __weak MyModelClass *weakSelf = self;
    // Make HTTP calls here, assume obj is returned value.
    // Convert network response to your data structure
    MyCustomDataRepresentationObj *objData = [MyCustomDataRepresentationObj alloc] initWith:obj];
    // Now hold on to that obj in a property
    weakSelf.data = objData;
    // Return back the data
    onComplete(objData, error);
    } else {
    onComplete(objData, nil); // Return pre fetched data;
    }
}

現在,在視圖控制器中,您將必須調用模型類方法,該方法將依次進行網絡調用(如果需要)並在完成塊中返回數據。

View Controller 1
-----------------

-(void)viewDidLoad
{
    // This is where the trick is, it returns the same object everytime.
    // Hence your data is temporarily saved while your app is running.
    // Another trick is that this can be accessed from other places too !
    // Like in next view controller.
    MyModel *myModelObj = [MyModel sharedModel];
    // You can call where ever data is needed.
    [myModelObj fetchMapDataWithCompletionBlock:^(id response, NSError *error){
        if (!error) {
            // No Error ! do whats needed to populate view
        }
    }];
}

在其他視圖控制器中執行相同的操作。

View Controller 2
-----------------

-(void)viewDidLoad
{
    // Gets the same instance which was used by previous view controller.
    // Hence gets the same data.
    MyModel *myModelObj = [MyModel sharedModel];
    // Call where ever data is needed.
    [myModelObj fetchMapDataWithCompletionBlock:^(id response, NSError *error){
        if (!error) {
            // No Error ! do whats needed to populate view
        }
    }];
}

注意:我剛剛在這里寫下了這些代碼行,可能存在語法錯誤。 它只是為了獲得基本的想法。

UITabBarController充當容器。 因此,從2個子ViewController中,您可以使用parentViewController屬性訪問parentViewController

因此,如果您想與兩個子ViewController共享相同的數據,則可以獲取數據並將其存儲在UITabBarController中。 而且,您可以從UIViewControllers像這樣訪問它

MyCustomTabBarController *tabBar = (MyCustomTabBarController*)self.parentViewController;
id data = tabBar.myCustomData;

使用Singleton Patterns可以在AppDelegate.m創建一個singleton類並初始化singleton實例,這樣您就可以通過以下方式從AppDelegate中訪問您的singleton類實例:

數據獲取對象怎么樣? 制作一個新類,該類請求您的數據位並將結果存儲在內部。

然后,您可以使用多種不同的方法將數據放入ViewController中:

直接參考在設置選項卡欄控制器上的viewControllers屬性之前,將此對象與每個ViewController關聯為ViewControllers的屬性。

您到該新類的接口可以包括一組獲取的結果,以及一種告訴對象獲取更多結果的方法(可能在請求完成時帶有回調)。

通知中心您的對象可以在有更多數據時發布通知,並且只包含一種開始請求更多數據的方法。

委派+注冊您可以為想要了解數據集更改的對象創建協議,確保所有必需的ViewController都符合,並在數據獲取對象上具有委托NSArray屬性。 這比Notification Center手動得多,但是如果您需要一個非常強大的界面,它會稍微容易一些。

不用說,有很多方法可以解決此問題,但是它們都始於指定一個類來執行獲取/存儲數據的特定任務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM