Нысандарды NSMutableArray-ке менің негізгі көрініс контроллерімде екінші көру реттегішінен қосыңыз, ios

Мен мұны қалай істейтінімді таңертең іздеп жүрмін. Менде View Controllers бар. Түбірден View Controller ( ViewControllerA - кесте көрінісінің контроллері болып табылатын) екінші көрініс контроллеріне ( ViewControllerB ) өтуге болады.

In the ViewControllerB, there are two fields: contacts & textBody. When the user is done they can click on "Add". This will then go back to ViewControllerA. What I am trying to do now, is for every time that process occurs, all the information from ViewControllerB the user just added goes into a cell in ViewControllerA. The user can then add as many cells as they like.

Алайда, мүмкін емес нәрсе, көзқарас контроллері арқылы ақпарат алу. Мен барлық таңертең бағдарламаны делегат, синглонстар, протоколдар, бөлісу қасиеттері және т.б. қолдану арқылы қарадым! Бірақ мен әлі күнге дейін тоқталдым.

What I want to do, but can't, is for every time the user clicks "Add" on ViewControllerB, contacts & texts are put into an array. This array is then put into another array which holds all the smaller arrays which the user has created? If you have an ideas, or links to similar/sample code or tutorials, that would be much appreciated!

2

9 жауаптар

Делегат әдісін келесідей қолданып көріңіз

XIB үлгілерімен жоба үлгісін жүктеу

Үлгі жобасын жүктеп алыңыз

ParentViewController.h

#import 

@interface ParentViewController : UIViewController {    
    NSMutableArray *dataArray;
}
- (void)passData:(NSMutableArray *)array;
@end

ParentViewController.m

#import "ParentViewController.h"
#import "ChildViewController.h"

@implementation ParentViewController

- (void)viewDidLoad {
    [super viewDidLoad];

   //Initialise the mutable array.
    dataArray = [[NSMutableArray alloc] init];
}

- (IBAction)btnGoToSecondView:(id)sender {
    ChildViewController *secondVC = [[ChildViewController alloc] initWithNibName:@"ChildViewController" bundle:nil];
    secondVC.delegate = self;
    [self presentViewController:secondVC animated:YES completion:nil];
}

- (void)passData:(NSMutableArray *)array {
    [dataArray addObject:array];
    NSLog(@"Data Passed = %@",dataArray);
}
@end

ChildViewController.h

#import 
#import "ParentViewController.h"

@class ParentViewController;

@interface ChildViewController : UIViewController {    
    NSMutableArray *tempArray;
}

@property (strong, nonatomic) IBOutlet UITextField *txtContact;
@property (strong, nonatomic) IBOutlet UITextField *txtTextBody;
@property(nonatomic, assign) ParentViewController *delegate;
@end

ChildViewController.m

@implementation ChildViewController

- (void)viewDidLoad {
    [super viewDidLoad];

   //Initialise the mutable array.
    tempArray = [[NSMutableArray alloc] init];
}

- (IBAction)btnPassDataBack:(id)sender {
    if([self.delegate respondsToSelector:@selector(passData:)]) {

        [tempArray addObject:_txtContact.text];
        [tempArray addObject:_txtTextBody.text];

        [self.delegate passData:tempArray];
    }
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)viewDidUnload {
    [self setTxtContact:nil];
    [self setTxtTextBody:nil];
    [super viewDidUnload];
}
@end

Стартбоймен

If you are using storyboard then create a ParentViewController segue ChildViewController and give it a identifier in my sample it showChildView

Делегияны орнату үшін келесі кодты пайдаланыңыз

// Calling the segue to go to the child view and setting up the delegate.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"showChildView"]) {
        ChildViewController *childVC = segue.destinationViewController;
        childVC.delegate = self;
    }
}

Содан кейін ParentViewController-ге қайтару үшін келесі кодты (менің үлгісімнен)

- (IBAction)btnPassDataBack:(id)sender {
    if([self.delegate respondsToSelector:@selector(passData:)]) {

        [tempArray addObject:_txtContact.text];
        [tempArray addObject:_txtTextBody.text];

        [self.delegate passData:tempArray];
    }
    [self.navigationController popToRootViewControllerAnimated:YES];
}
2
қосылды
@falky жоғарыда көрсетілген кодты көріңіз. ол сіздің қажеттілігіңізге сәйкес жұмыс істейді. Тікелей көшіріп алсаңыз, үлгі кодын қоса аласыз
қосылды автор icodebuster, көзі
@falky үлгілік жобаны тексеріңіз. Мен сценарийдің үлгі кодын, сондай-ақ түсіндірмеге қосылдым.
қосылды автор icodebuster, көзі
Бұл шынында да пайдалы болды! Рақмет сізге. Жалғыз нәрсе - оны әңгімелесу парағын қалай қолдануға болатынын білмеймін (мен бұқаларды пайдаланбаймын). Сондай-ақ, осы жолдағы childViewController.h файлында қате пайда болды: @property (nonatomic, assign) ParentViewController * delegate; Мен оны қалай түзетуге болатынына сенімді емеспін. Бірақ сіздің көмегіңізге рахмет
қосылды автор falky, көзі
Әңгімелесу үлгісі жақсы болар еді. Мен оны жауап ретінде қабылдаймын. Үлкен рахмет! Біріншіден, мен UINvaigation контроллерін пайдаланамын, екіншіден, сипаттың қатесі: «Талдау мәселесі, белгісіз түрдегі атауы» ViewControllerA «» ... tableViewController екендігін білу маңызды ма?
қосылды автор falky, көзі
Өте пайдалы! Көңілділер :)
қосылды автор falky, көзі

Егер ақпарат шынымен «ғаламдық» болса, ол бүкіл бағдарлама бойынша бір данасы бар - онда DB80Buckeye ұсынғандай, сіз синглтон жасауыңыз керек.

Егер ақпарат шынымен ViewController1-ге тиесілі болса және оның ViewController2 түрінде өзгертілуін қаласаңыз (яғни ViewController2 шынымен ViewController1 бөлігі болса, ол тек басқа экранда болуы керек), содан кейін ViewController2 конструкторының бөлігі .

-(void)view_controller_1_that_push_view_controller_2_onto_the_stack {
     ViewController2* vc2 = [[ViewController2 alloc] initWithInformation:your_information];
     [self.navigationController pushViewController:vc2 animated:YES];
}

@interface ViewController2 

-(id)initWithInformation:(YourInformationClass*)info;

@end

Басқа тәсіл - хабарламаларды пайдалану.

1
қосылды

Егер ақпарат шынымен «ғаламдық» болса, ол бүкіл бағдарлама бойынша бір данасы бар - онда DB80Buckeye ұсынғандай, сіз синглтон жасауыңыз керек.

Егер ақпарат шынымен ViewController1-ге тиесілі болса және оның ViewController2 түрінде өзгертілуін қаласаңыз (яғни ViewController2 шынымен ViewController1 бөлігі болса, ол тек басқа экранда болуы керек), содан кейін ViewController2 конструкторының бөлігі .

-(void)view_controller_1_that_push_view_controller_2_onto_the_stack {
     ViewController2* vc2 = [[ViewController2 alloc] initWithInformation:your_information];
     [self.navigationController pushViewController:vc2 animated:YES];
}

@interface ViewController2 

-(id)initWithInformation:(YourInformationClass*)info;

@end

Басқа тәсіл - хабарламаларды пайдалану.

1
қосылды

Немесе делегат төмендегілерді пайдалануды ұсынады: ViewControllerA.h:

 @property (nonatomic, strong) ViewControllerB* viewControllerB; 

ViewControllerA.m ішінде

if (!self.viewControllerB)
{
     self.viewControllerB = [[ViewControllerB alloc] initWithNibName: @"ViewControllerBr"                                                                                                 bundle: nil];      
}
[self.navigationController pushViewController: self.viewControllerB
                                     animated: YES];

...

- (void) viewWillAppear: (BOOL) animated

   if (self.viewControllerB)
   {
       NSString* contact = self.viewControllerB.contact;
       NSLog(@"%@", contact);
   } 

...

1
қосылды

Немесе делегат төмендегілерді пайдалануды ұсынады: ViewControllerA.h:

 @property (nonatomic, strong) ViewControllerB* viewControllerB; 

ViewControllerA.m ішінде

if (!self.viewControllerB)
{
     self.viewControllerB = [[ViewControllerB alloc] initWithNibName: @"ViewControllerBr"                                                                                                 bundle: nil];      
}
[self.navigationController pushViewController: self.viewControllerB
                                     animated: YES];

...

- (void) viewWillAppear: (BOOL) animated

   if (self.viewControllerB)
   {
       NSString* contact = self.viewControllerB.contact;
       NSLog(@"%@", contact);
   } 

...

1
қосылды

Мен сіздің NSMutableDictionary-ң синглтон данасын пайдалануды ұсынар едім, себебі олар мені сіздің нақты жағдайыңыздан бірнеше мәрте (соның ішінде пайдаланушы құрылымдарымен және UITabBarControllers-тен) алып тастады. Мен синглтонды енгізу үшін қолданатын мысал. Бұл әдіс-ақ ARC-қауіпсіз болып табылады

mySingleton.h

#import 

@interface mySingleton : NSObject {

}
+ (NSMutableDictionary *) myMutableDict;

@end

mySingleton.m

#import "mySingleton.h"

@implementation mySingleton

+ (NSMutableDictionary *)myMutableDict
{
    static NSMutableDictionary *singletonInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        singletonInstance = [[NSMutableDictionary alloc]init];

    });
    return singletonInstance;
}

@end

As long as you include mySingleton.h in all of your view controllers you can access the data via [mySingleton myMutableDict]. For example: [[mySingleton myMutableDict] setObject:myObject forKey:myKey];

Іске сәт!

1
қосылды

Мұнда екі жол бар. Бұл әрекетті орындаудың стандартты үлгісі делегация болып табылады. Сізге синглон қажет емес. ViewControllerA сіздің деректеріңізді басқарады және тізімдейді. ViewControllerB осы деректердің бәрі туралы ештеңе білудің қажеті жоқ, сондықтан оны синглетон арқылы ашудың қажеті жоқ және т.б.

ViewControllerB тақырыбындағы файлдағы делегат хаттамасын жасаңыз. Сол сияқты бірнәрсе:

@protocol ViewControllerBDelegate
- (void)addContact:(NSString *)contact withBody:(NSString *)textBody;
@end

Енді ViewControllerA делегат хаттамасын оның тақырыбына енгізетінін көрсетіңіз:

@interface ViewControllerA : UIViewController 

ViewControllerA. тақырыбының жоғарғы жағындағы ViewControllerB.h импорттауды ұмытпаңыз.

ViewControllerA ішіндегі іске асыру кезінде хаттамада көрсетілген делегат әдісін қолданыңыз:

- (void)addContact:(NSString *)contact withBody:(NSString *)textBody {
    [self.someArray addObject:[[SomeObject alloc] initWithContact:contact body:textBody]];
    [self.tableView reloadData];
}

Мұның бәрі бір ғана мысал. Деректер құрылымын қалай басқаратыныңызға сенімді емеспін және ұяшықты мағынасы бар жерді кірістіру дұрысырақ.

ViewControllerB тақырыбындағы делегат сілтемесін жариялау:

@property (weak, nonatomic) id delegate;

ViewControllerB ұсынған кезде, делегат ретінде ViewControllerA параметрін орнатыңыз.

ViewControllerB *b = [[ViewControllerB alloc] init...];
b.delegate = self;

ViewControllerB ішіндегі қосу түймешігі арқылы іске қосылатын селекторда, көріністі басқару құралын шарлау бумасынан өшірмес бұрын делегатқа қайта қоңырау шалыңыз:

[self.delegate addContact:contact withBody:text];

онда contact және text - пайдаланушы енгізген мәндер.

Сондай-ақ делегаттың орнына блокты қолдануға болады, бірақ принцип - бірдей - екінші көрініс контроллері ғана сіздің деректеріңізді қабылдау үшін жауапты болады және деректерді басқаратын қараушы контроллеріне жібереді.

1
қосылды

Мұнда екі жол бар. Бұл әрекетті орындаудың стандартты үлгісі делегация болып табылады. Сізге синглон қажет емес. ViewControllerA сіздің деректеріңізді басқарады және тізімдейді. ViewControllerB осы деректердің бәрі туралы ештеңе білудің қажеті жоқ, сондықтан оны синглетон арқылы ашудың қажеті жоқ және т.б.

ViewControllerB тақырыбындағы файлдағы делегат хаттамасын жасаңыз. Сол сияқты бірнәрсе:

@protocol ViewControllerBDelegate
- (void)addContact:(NSString *)contact withBody:(NSString *)textBody;
@end

Енді ViewControllerA делегат хаттамасын оның тақырыбына енгізетінін көрсетіңіз:

@interface ViewControllerA : UIViewController 

ViewControllerA. тақырыбының жоғарғы жағындағы ViewControllerB.h импорттауды ұмытпаңыз.

ViewControllerA ішіндегі іске асыру кезінде хаттамада көрсетілген делегат әдісін қолданыңыз:

- (void)addContact:(NSString *)contact withBody:(NSString *)textBody {
    [self.someArray addObject:[[SomeObject alloc] initWithContact:contact body:textBody]];
    [self.tableView reloadData];
}

Мұның бәрі бір ғана мысал. Деректер құрылымын қалай басқаратыныңызға сенімді емеспін және ұяшықты мағынасы бар жерді кірістіру дұрысырақ.

ViewControllerB тақырыбындағы делегат сілтемесін жариялау:

@property (weak, nonatomic) id delegate;

ViewControllerB ұсынған кезде, делегат ретінде ViewControllerA параметрін орнатыңыз.

ViewControllerB *b = [[ViewControllerB alloc] init...];
b.delegate = self;

ViewControllerB ішіндегі қосу түймешігі арқылы іске қосылатын селекторда, көріністі басқару құралын шарлау бумасынан өшірмес бұрын делегатқа қайта қоңырау шалыңыз:

[self.delegate addContact:contact withBody:text];

онда contact және text - пайдаланушы енгізген мәндер.

Сондай-ақ делегаттың орнына блокты қолдануға болады, бірақ принцип - бірдей - екінші көрініс контроллері ғана сіздің деректеріңізді қабылдау үшін жауапты болады және деректерді басқаратын қараушы контроллеріне жібереді.

1
қосылды

Мұнда екі жол бар. Бұл әрекетті орындаудың стандартты үлгісі делегация болып табылады. Сізге синглон қажет емес. ViewControllerA сіздің деректеріңізді басқарады және тізімдейді. ViewControllerB осы деректердің бәрі туралы ештеңе білудің қажеті жоқ, сондықтан оны синглетон арқылы ашудың қажеті жоқ және т.б.

ViewControllerB тақырыбындағы файлдағы делегат хаттамасын жасаңыз. Сол сияқты бірнәрсе:

@protocol ViewControllerBDelegate
- (void)addContact:(NSString *)contact withBody:(NSString *)textBody;
@end

Енді ViewControllerA делегат хаттамасын оның тақырыбына енгізетінін көрсетіңіз:

@interface ViewControllerA : UIViewController 

ViewControllerA. тақырыбының жоғарғы жағындағы ViewControllerB.h импорттауды ұмытпаңыз.

ViewControllerA ішіндегі іске асыру кезінде хаттамада көрсетілген делегат әдісін қолданыңыз:

- (void)addContact:(NSString *)contact withBody:(NSString *)textBody {
    [self.someArray addObject:[[SomeObject alloc] initWithContact:contact body:textBody]];
    [self.tableView reloadData];
}

Мұның бәрі бір ғана мысал. Деректер құрылымын қалай басқаратыныңызға сенімді емеспін және ұяшықты мағынасы бар жерді кірістіру дұрысырақ.

ViewControllerB тақырыбындағы делегат сілтемесін жариялау:

@property (weak, nonatomic) id delegate;

ViewControllerB ұсынған кезде, делегат ретінде ViewControllerA параметрін орнатыңыз.

ViewControllerB *b = [[ViewControllerB alloc] init...];
b.delegate = self;

ViewControllerB ішіндегі қосу түймешігі арқылы іске қосылатын селекторда, көріністі басқару құралын шарлау бумасынан өшірмес бұрын делегатқа қайта қоңырау шалыңыз:

[self.delegate addContact:contact withBody:text];

онда contact және text - пайдаланушы енгізген мәндер.

Сондай-ақ делегаттың орнына блокты қолдануға болады, бірақ принцип - бірдей - екінші көрініс контроллері ғана сіздің деректеріңізді қабылдау үшін жауапты болады және деректерді басқаратын қараушы контроллеріне жібереді.

1
қосылды