MAX*_*MAX 24 uiviewcontroller ios segue
我是iOS新手.我在ViewControllers之间传递数据时遇到问题.我有三个viewControllers(view_1,view_2和view_3).
在这里我的设置: -
我想将'view_1'的ViewController引用(id)发送到'view_3'.所以我包含include "view_3"在'view_1'中并将值设置为'view_3'变量(使用view_3 *v3=[[view_3 alloc] init ]; v3.reference=self;).在控制台中显示:
查看控制器: - ; <ViewController:0x89e9540>
在'view_1'但在'view_3'中,在它显示的控制台中
视图控制器(null)
但是当我使用'view_2'传递这些数据时它的工作.但是怎么样?我想知道这种行为,是否有任何解决方案来创建这个?
请帮忙.
Cou*_*per 46
当触发segue时,"将数据传递到目标控制器"将通过覆盖方法实现prepareForSegue:sender:.
通常,您将数据而不是源视图控制器传递到目标视图控制器."数据"可能是您的应用程序"模型"的某个方面.它是像"User"这样的对象,或者可能是包含"User"等的数组.
该目标视图控制器应不会有任何知识源视图控制器.这意味着,目标视图控制器不需要导入源视图控制器的标头.
另一方面,源视图控制器可以知道目标视图控制器的具体类或目标视图控制器的基类,因此将导入目标视图控制器的头.
请参阅:触发Segue时配置目标控制器
如果在源和目标之间需要某种"通信协议",则可以使用委派与其他视图控制器进行通信.这涉及@protocol的定义(例如,具有方法doneButton)和delegate在目标视图控制器中定义的属性.如果协议应特定于目标视图控制器,则应在目标视图控制器的标头中定义该协议.通常,您从目标控制器的角度定义协议,而不是源控制器的要求.
然后,源视图控制器创建一个委托(除非它本身就是它)并设置delegate目标视图控制器的.目标视图控制器将委托方法发送给委托,委托处理它.
现在,将"数据"从VC_A传递到VC_B应该是直截了当的.您应该阅读一些使用的示例prepareForSegue:sender:.例如,目的地视图控制器可以具有一个属性data,它表示事它应该显示.源视图控制器必须在此中设置此属性prepareForSegue:sender:.
通过VC_B将数据从VC_A传递到VC_C也应该是直截了当的.
注意:每个视图控制器可以调整(独立的,修改,制备,切片,变换等)其 data使之成为适合data用于下一个视图控制器.
如果VC_C需要其源视图控制器VC_B中不可用的数据,那么有几种方法可以解决这个问题.然而,这通常是糟糕设计的标志.
您可以拥有一个全局的应用程序模型.假设,您的"应用程序模型"是类型的对象Document.假设,在任何时候只有该应用程序模型的一个实例.然后,该模型是一个"单例",可以从您的应用程序中的任何位置访问,如下所示:
Document* document = [Document sharedDocument];
Run Code Online (Sandbox Code Playgroud)
但是,获取模型实例的首选方法是在第一个需要访问它的视图控制器中,在这种情况下:VC_A.
然后,VC_A将Document实例传递给下一个视图控制器VC_B.VC_B将文档对象传递给VC_C.
您应该阅读官方文档" View Controller Programming Guide for iOS ".
假设您有一个"用户"列表.该列表应显示在表视图控制器中,并且还应该有一个详细视图,显示一个用户的详细信息.
表视图控制器将具有"数据"属性users:
在UsersTableViewController.h中:
@interface UsersTableViewController : UIViewController
@property (nonatomic, readonly) NSArray* users;
@end
Run Code Online (Sandbox Code Playgroud)
(严格地说,此user属性不需要公开.例如,如果表视图在内部获取用户自己的列表,则无需从外部访问它.
"users"数组是表视图的数据,应以行的形式显示.每行显示用户的"摘要".
应在详细视图控制器中显示用户的更多详细信息.详细视图控制器的数据是单个类型的用户User.
当用户在表视图中选中某一行时,将显示详细视图控制器.在显示之前,表视图控制器必须配置详细视图控制器:表视图控制器为当前所选用户分配详细视图控制器的"数据属性" .因此,详细视图控制器应具有公共属性user:
@interface UserViewController : UIViewController
@property (nonatomic) User* user;
@end
Run Code Online (Sandbox Code Playgroud)
表视图控制器在以下位置配置详细视图控制器 prepareForSegue:sender::
在UsersTableViewController.m中
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"ShowUserDetails"]) {
UserViewController* userViewController = [segue destinationViewController];
userViewController.user = [self.users objectInListAtIndex:[self.tableView indexPathForSelectedRow].row];
}
}
Run Code Online (Sandbox Code Playgroud)
第二个例子更复杂,并使用"委托"作为在控制器之间建立通信的手段.
警告:
这不是一个完整的例子.本示例的目的是演示如何使用"委派".如示例中所示的全功能数据任务实现将需要更多的努力.在这种情况下,"委托"将是实现这一目标的最优选方法(恕我直言).
假设我们想要
从详细视图中.
这些"数据任务"不应由详细视图控制器本身执行,而是委托负责这些数据任务.
这些数据操作应由代表处理:
@protocol UserDataSourceDelegateProtocol <NSObject>
- (User*) viewControllerUser:(UserViewControllerBase*)viewController;
- (void) viewController:(UserViewControllerBase*)viewController dismissWithUpdatedUser:(User*)user;
- (void) viewController:(UserViewControllerBase*)viewController dismissWithDeletedUser:(User*)user;
- (void) viewController:(UserViewControllerBase*)viewController dismissWithCreatedUser:(User*)user;
@end
Run Code Online (Sandbox Code Playgroud)
该协议反映了基本的CRUD方法(创建,读取,更新,删除).
同样,我们不希望Detail View Controller 本身执行这些数据方法,而是由实现该方法的实例执行UserDataSourceDelegateProtocol.详细视图控制器具有此委托的属性,并将这些"数据任务"发送给委托.
可能有几个详细视图控制器,抽象类的所有子类UserViewControllerBase,用于处理显示,编辑和创建任务.可以在表视图和"显示用户"视图控制器中执行用户删除:
ShowUserViewControllerEditUserViewControllerNewUserViewController例如,当用户选中"后退"按钮并且用户已修改用户对象时,EditUserViewController将发送viewController:dismissWithUpdatedUser:.现在,代表可能允许也可能不允许关闭详细视图.例如,当存在验证错误时,它可能会禁止它.
该UserDataSourceDelegateProtocol协议可以在根视图控制器中实现,例如表视图控制器.但是,一个单独的类,其唯一的责任是处理数据任务可能更合适.在下面的示例中,表视图控制器也将是此数据处理程序.
所述UserDataSourceDelegateProtocol可在附加标题来限定.
在UsersTableViewController.m中:
#import "UserDataSourceDelegateProtocol.h"
#import "ShowUserViewController.h"
@interface UsersTableViewController () <UserDataSourceDelegateProtocol>
@property (nonatomic, readonly) NSArray* users;
@end
// This delegate will be called when the detail view controller request
// the user object which shall be displayed.
- (User*) viewControllerUser:(UserViewControllerBase*)viewController {
return [self.users objectInListAtIndex:[self.tableView indexPathForSelectedRow].row];
}
Run Code Online (Sandbox Code Playgroud)
这里,Table View Controller配置Show User Detail View Controller:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:UserShowSegueID])
{
ShowUserViewController* showViewController = segue.destinationViewController;
showViewController.delegate = self; // Data Source Handler is self
}
}
Run Code Online (Sandbox Code Playgroud)
"编辑用户"视图控制器通常是"显示用户"视图控制器的目标视图控制器,当用户选中"编辑"按钮时,该控制器将被查看.
"显示用户"视图控制器将为"编辑用户"视图控制器设置委托获取相同的委托:
在ShowUserViewController.m中
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:UserEditSegueID])
{
EditUserViewController* editViewController = segue.destinationViewController;
editViewController.delegate = self.delegate; // pass through the data source hanlder
}
}
Run Code Online (Sandbox Code Playgroud)
数据委托可以按如下方式处理更新的用户:
在UsersTableViewController.m中:
- (void) viewController:(UserViewControllerBase*)viewController
dismissWithUpdatedUser:(User*)user {
if (/* is valid user and can be saved */) {
[viewController.presentingViewController dismissViewControllerAnimated:YES
completion:nil];
}
}
Run Code Online (Sandbox Code Playgroud)
Sur*_*gch 12
YouTube上的这个Swift项目帮助我终于明白了如何做到这一点.
我按类似的方式设置了一个简单的例子.在文本字段中写入一些文本,按下按钮,然后将文本放在下一个视图控制器的标签中.
这不是很困难.在Interface Builder中创建故事板布局.要制作segue,只需control单击按钮并拖动到第二视图控制器即可.
第一视图控制器的代码是
import UIKit
class FirstViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
// This function is called before the segue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// get a reference to the second view controller
let secondViewController = segue.destinationViewController as! SecondViewController
// set a variable in the second view controller with the String to pass
secondViewController.receivedString = textField.text!
}
}
Run Code Online (Sandbox Code Playgroud)
而第二视图控制器的代码是
import UIKit
class SecondViewController: UIViewController {
@IBOutlet weak var label: UILabel!
// This variable will hold the data being passed from the First View Controller
var receivedString = ""
override func viewDidLoad() {
super.viewDidLoad()
// Used the text from the First View Controller to set the label
label.text = receivedString
}
}
Run Code Online (Sandbox Code Playgroud)
UITextField和UILabel.将数据传递到第三视图控制器的过程将是相同的.
| 归档时间: |
|
| 查看次数: |
36872 次 |
| 最近记录: |