本文介绍了ipad uisplitview:将数据从masterviewcontroller传递到uiviewcontroller(通过segue重定向)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是iOS编程的新手,所以我想从头开始制作此书,以便能够了解整个书的工作原理.因此,我没有使用主细节模板,而是从头开始了.

I'm new to iOS programming so I want to make this thing from scratch to be able understand how the whole thing works. So instead of using the master detail template I did this from the ground up.

就在主视图和详细视图之间传递数据而言,我遇到了很大的障碍.此刻,每当我点击主视图的项目时,它将在详细视图控制器上寻找第一个视图,我们称其为mainswitchviewcontroller.这是第一个通过segue连接到UINavigationController的细节控制器部分的ViewController(请参见下图).

I'm having a huge roadblock in terms of passing data between the master view and the detail view. At the moment, whenever I tap on the item of the master view it would look for the first view on the detail view controller, let's call it mainswitchviewcontroller. It's the first ViewController connected via segue to the UINavigationController for the detail controller part (Please refer to image below).

这种情况发生在登录后,它显示viewcontroller,我希望用户在访问整个应用程序之前先选择一个选项.这将导致它们到达流程的最后一个ViewController(请参见下图-红色圆圈).

This happens after login where it shows that viewcontroller, I want the user to pick an option before accessing the whole app. which will lead them to the last ViewController of the flow (refer to the image below - red circle).

现在我要这样做的是:

@interface MasterListViewController : UITableViewController{
}

@property (nonatomic) int matNum;
@property (strong, nonatomic) DetailStaffMainContentViewController *detailViewController;
@end

:
:

@implementation MasterListViewController
@synthesize matNum;
:
:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    for(UIViewController *vc in self.splitViewController.viewControllers){
        NSLog(@"%@)", vc.title);
    }

    self.detailViewController.teststring = @"gronk";
}

这是我的detailViewController(我要访问的那个)

This is my detailViewController (the one I want to access)

@implementation DetailStaffMainContentViewController
@synthesize tableView;
@synthesize teststring;
@synthesize lblOutput;

现在在选择该行时,我指定要用于在控制器上填充该标签的teststring.那就是我所做的.

Now on select of the row, I assign the teststring which I want to use to populate that label on the controller. That's what I did.

我的问题是:

  1. 我遇到了错误.想知道我在做什么错吗?

  1. I'm getting an error. Wondering what I was doing wrong?

[MainSwitchBoardViewController setTeststring:]: unrecognized selector
sent to instance 0x7572190

  • 这是推荐的数据传递方式吗?还是我应该坚持使用通知中心?

  • Is this a recommended way of passing data? Or should I just stick with notificationcenters?

    有想法吗?

    编辑只是为了让您了解应用程序的流程:

    EDITJust to give you on the flow of the app:

    1. 用户登录(如果不存在用户名,则会弹出浮动ViewController并强制用户登录.

    1. User logs in (if username does not exist, the floating viewcontroller will pop up and force the user to log in.

    用户登录后,弹出窗口消失,然后询问用户当前会话中将使用哪种类型的角色(例如,工作人员或战斗人员).

    Once the user logs in, the pop up goes away and then asks the user what type of role is to be used in the current session (eg. staff or fighter).

    如果用户选择战斗机,则将用户推到顶部的VC如果用户选择人员,则将用户推到底部的VC(集合控制器)

    If the user picks fighter, it pushes the user to the top VC If the user picks staff, it pushes the user to the bottom VC (collections controller)

    FOR工作人员:目前,我正在使用此[self perfermSegueWithIdentifier:sender:self]推送到最后一个VC

    FOR Staff: At the moment I'm pushing to the last VC with this [self perfermSegueWithIdentifier:sender:self]

    一旦向用户显示了最后一个VC(DetailsS​​taffView),我希望它成为用户进行交易的主要Details View.还有几个弹出窗口? (或者可能需要添加针对特定交易的另一VC推送).但是最终我不希望该用户访问第一个Viewcontroller(MasterSwitchBoard)

    Once the user gets shown the last VC (DetailsStaffView), I want this to be the main Details View where the user does it's transaction. A few more pop ups? (Or maybe another push to another VC for specific transaction needs to be added). But ultimately I don't want the user to access the first Viewcontroller (MasterSwitchBoard)

    编辑2 这是登录后控制第一个VC的主配电板类.

    EDIT 2This is the main switch board class that controls the first VC after login.

    @interface MainSwitchBoardViewController : UIViewController{
    
    }
    
    @property (strong, nonatomic) IBOutlet UILabel *txtLabel;
    - (IBAction)btnStaff:(id)sender;
    - (IBAction)btnAdmin:(id)sender;
    
    @end
    

    这是atm自动推送到最后一个VC的集合VC.一开始我是在使用通知,但似乎没有必要,所以我将其取出.

    This is the collections VC which atm automatcially pushes to the last VC. In the beginning I was using a notification on this but it seems like it's not necessary so I took it out.

    @interface MatListCollectionViewController ()
    
    @end
    
    @implementation MatListCollectionViewController
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
    
        [self performSegueWithIdentifier:@"SeguePushToStaffDetailFromMats" sender:self];
    }
    

    然后是详细信息人员

    @interface DetailStaffMainContentViewController : UIViewController{
    
    }
    
    @property (strong, nonatomic) IBOutlet UITableView *tableView;
    @property (nonatomic, retain) IBOutlet UILabel *lblOutput;
    @property (nonatomic, retain) NSString *teststring;
    
    @end
    
    
        @implementation DetailStaffMainContentViewController
        @synthesize tableView;
        @synthesize teststring;
        @synthesize lblOutput;
    

    推荐答案

    我将以相反的顺序处理这些问题:

    I'll tackle those in reverse order:

    理论上您可以使用通知中心,但在这种情况下我不会.就个人而言,我仅在以下情况下使用NSNotificationCenter

    You theoretically could use notification center, but I wouldn't in this case. Personally, I only use NSNotificationCenter if:

    • 我正在执行异步过程,该过程没有合理的方式来了解视图控制器的状态(例如,我有一些后台任务正在做一些耗时的来自服务器的数据更新,并且用户可能已经导航了当我准备通知视图控制器更新已完成时,将其移至应用程序中的几乎任何位置);和/或

    • I'm doing asynchronous process which has no reasonable way of knowing the state of the view controllers (e.g. I have some background task that's doing some time consuming update of data from a server, and the user could have navigated to just about anywhere in the app by the time I'm ready to notify the view controllers that the update is done); and/or

    我可能有多个要通知某些事件的对象.

    I potentially have multiple objects that I want to notify of some event.

    这两个条件均不适用.当然可以使用NSNotificationCenter,但这应该是不必要的.通常最好显式设置属性.

    Neither of those conditions apply here. Certainly you could use NSNotificationCenter, but that should be unnecessary. Explicitly setting properties is generally preferable.

    不幸的是,根据您到目前为止提供的证据很难说.但是根据您的代码和注释,我在协调方面有些问题:

    Unfortunately, it's hard to say on the basis of the evidence you've presented thus far. But there are a few things that I'm having trouble reconciling on the basis of your code and comments:

    • 您已声明detailViewControllerDetailStaffMainContentViewController(这是您合成teststring访问器的类);

    • You've declared detailViewController to be a DetailStaffMainContentViewController (and that's the class for which you've synthesized the teststring accessors);

    但是您的错误消息表明detailViewController显然是MainSwitchBoardViewController对象(它不理解setTeststring访问器方法);和

    But your error message suggests that detailViewController is clearly a MainSwitchBoardViewController object (which doesn't understand the setTeststring accessor method); and

    您尚未向我们展示您如何设置detailViewController,因此很难在这里说出您哪里出了错.

    You haven't shown us how you're setting detailViewController, so it's hard to say where you've gone wrong here.

    就个人而言,在这种情况下,我总是不愿意定义属性来维护指向视图控制器的指针.通常,我倾向于问UISplitViewController拆分中的内容是什么.因此,在我的主视图控制器中,没有这样的类属性/ivar,而是有这样的方法:

    Personally, in cases like this, I'm always reticent to define properties to maintain pointers to view controllers. I'd generally be inclined to ask the UISplitViewController what's in the detail split. So, rather than having a class property/ivar for that, in my master view controller, I have a method like:

    - (UIViewController *)detailViewController
    {
        return [[self.splitViewController.viewControllers lastObject] topViewController];
    }
    

    基本上是说从我的拆分视图控制器的viewControllers数组(详细信息拆分)中获取最后一个对象,并且由于我(个人)始终在该详细信息拆分中使用导航控制器,所以我们使用topViewController来获取指向我的子类UIViewController的指针,该子类已进行了详细的分割(嵌入在导航控制器中).

    That's basically saying "get the last object from my split view controller's array of viewControllers (the detail split) and because I (personally) always use a navigation controller in that detail split, let's use the topViewController to get a pointer to my subclassed UIViewController that's in that detail split (embedded within the navigation controller).

    然后我进行didSelectRowAtIndexPath检查,以查看该视图控制器是否是我所期望的.如果没有,我会选择它(并让prepareSegue将我想要的数据传递给该控制器).

    Then I have my didSelectRowAtIndexPath check to see if that view controller is the one I expected. If not, I segue to it (and have prepareSegue pass the data I want to that controller).

    例如,考虑以下故事板:

    So, for example, consider this storyboard:

    在这里,"A"是我的默认详细信息控制器. "B"可能是一些随机场景,我可能已将其替换为"A". "C"是我的实际详细信息视图控制器,在这里我可以看到我从主视图控制器的表视图中选择的项目的详细信息.因此,我的didSelectRowAtIndexPath用于主视图控制器可能看起来像:

    Here, "A" is my default detail controller. "B" might be some random scene that I may have replaced "A" with. And "C" is my real detail view controller where I can see the details for the item I selected from the master view controller's table view. Thus, my didSelectRowAtIndexPath for the master view controller might look like:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UIViewController *controller = [self detailViewController];
    
        if (![controller isKindOfClass:[DetailCViewController class]])
        {
            // if I'm not already showing "C" in my detail split, then let's segue to it
    
            [self performSegueWithIdentifier:@"GoToC" sender:self];
        }
        else
        {
            // if I'm already showing "C" in my detail split, let's just set the item of data I want to pass to it
    
            DetailCViewController *cController = (DetailCViewController *)controller;
    
            cController.detailItem = self.objects[indexPath.row];
        }
    
        // I have a method I call to make sure that the popover menu for the master view
        // controller disappears (in case it popped up since I was in portrait mode) and
        // adds the master view controller button to the navigation bar if I need it.
    
        [self removePopoverAndAddNavigationButton];
    }
    

    如果我需要连接到"C",我还可以根据需要让我的`prepareSegue传递detailItem:

    In case I needed to segue to "C", I also have my `prepareSegue pass the detailItem as needed:

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if ([segue.identifier isEqualToString:@"GoToC"])
        {
            DetailCViewController *cController = (DetailCViewController *)[segue.destinationViewController topViewController];
    
            cController.detailItem = self.objects[[[self.tableView indexPathForSelectedRow] row]];
        }
    }
    

    正如我所说,很难弄清楚为什么您的detailViewController具有错误的对象类型,但这就是我可能要解决的问题.

    As I said, trying to figure out why your detailViewController has the wrong type of object is hard to say, but this is how I might tackle something like this.

    这篇关于ipad uisplitview:将数据从masterviewcontroller传递到uiviewcontroller(通过segue重定向)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 10-20 12:03