xcode ios 以编程方式推送控制器视图,无需故事板或 xib
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22795239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ios push controller view programmatically without storyboards or xib
提问by denikov
In ViewControllerA I have a table with three rows of data right now (three messages). Clicking on a row, I'm trying to push to ViewControllerB with the text from one of the rows (the name). Problem I'm having is I'm trying to do everything programmatically, not using storyboard ids or storyboard segues. Is this possible? Here's what I have.
在 ViewControllerA 中,我现在有一个包含三行数据的表(三条消息)。单击一行,我试图将其中一行中的文本(名称)推送到 ViewControllerB。我遇到的问题是我试图以编程方式完成所有工作,而不是使用故事板 ID 或故事板转场。这可能吗?这就是我所拥有的。
ViewControllerA m.
视图控制器A m。
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
Messages *cell = (Messages *)[tableView cellForRowAtIndexPath:indexPath];
NSString *from = [NSString stringWithFormat:@"%@", cell.from.text];
ViewControllerB *VCB = [[ViewControllerB alloc]init];
VCB.from = from;
[self.navigationController pushViewController:VCB animated:YES];
//using this^ creates a new view controller with a black screen but passes the variable
//[self performSegueWithIdentifier:@"pushMessage" sender:self];
using this^ shows my ViewControllerB perfectly but the value isn't set
}
ViewControllerB h.
视图控制器 B h.
@property (strong, nonatomic) NSString *from;
ViewControllerB m.
视图控制器B米。
-(void)viewDidLoad{
NSLog(@"%@", from);
}
Is there a way to do this without initiating a new viewcontrollerB in VCA and getting the right push animation?
有没有办法在不启动 VCA 中的新 viewcontrollerB 并获得正确的推送动画的情况下做到这一点?
回答by Zack
I believe I understand what you're asking and you are almost on the right track here. You said that it works when you use [self performSegueWithIdentifier:@"pushMessage" sender:self];
but the value is not set.
我相信我明白你在问什么,你几乎走在正确的轨道上。你说你用的时候能用,[self performSegueWithIdentifier:@"pushMessage" sender:self];
但是没设置值。
So, declare an NSString "from" in your header and in the previous code delete the [self.navigationController pushViewController:CVC animated:YES];
所以,在你的头文件中声明一个 NSString "from" 并在前面的代码中删除 [self.navigationController pushViewController:CVC animated:YES];
//ViewControllerA.h
@property (copy, nonatomic) NSString *from;
//ViewControllerA.m
@synthesize from;
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Messages *cell = (Messages *)[tableView cellForRowAtIndexPath:indexPath];
from = [NSString stringWithFormat:@"%@", cell.from.text];
[self performSegueWithIdentifier:@"pushMessage" sender:self];
}
Then you need to use the prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
然后你需要使用 prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
//ViewControllerA.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"pushMessage"]) {
ViewControllerB *vcb = [segue destinationViewController];
[vcb setFrom:[self from]];
}
}
EDIT
编辑
Well, I feel like this is a really wrong way to do it. But, this will satisfy all of your conditions asked in the question. I have checked and this does in fact work:
好吧,我觉得这是一种非常错误的方法。但是,这将满足您在问题中提出的所有条件。我已经检查过,这确实有效:
First, Go to your storyboard, click on the View Controller B, click on the identity inspector and change the Storyboard ID. Also click the check that says "Use Storyboard ID".
首先,转到您的故事板,单击视图控制器 B,单击身份检查器并更改故事板 ID。同时单击“使用故事板 ID”的复选框。
In your ViewControllerA:
在您的 ViewControllerA 中:
//ViewControllerA.h
- (void)callViewControllerWithCellString:(NSString *)str;
//ViewControllerA.m
- (void)callViewControllerWithCellString:(NSString *)str
{
NSString * storyboardName = @"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
SecondViewController * vc = [storyboard instantiateViewControllerWithIdentifier:@"ViewControllerB"];
[vc setFrom:str];
[[self navigationController] pushViewController:vc animated:YES];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Messages *cell = (Messages *)[tableView cellForRowAtIndexPath:indexPath];
NSString *from = [NSString stringWithFormat:@"%@", cell.from.text];
[self callViewControllerWithCellString:from];
}
回答by Karim
So lets see if i understand this.
所以让我们看看我是否理解这一点。
- You want the text from the clicked row passed to the view controller that you want to present
- You want to do this without using storyboards
- 您希望将单击行中的文本传递给要呈现的视图控制器
- 你想在不使用故事板的情况下做到这一点
Sounds simple enough. Check this out.
听起来很简单。看一下这个。
// I actually recommend this option
// Simply initialize your view controller with the text that you want to pass
ViewControllerB * VCB = [[ViewControllerB alloc] initWithText:from];
// For this to work, you'll have to declare a new init method in your .h file like this
-(void)initWithText:(NSSTring *)text;
// You should also declare an iVar to store your text
NSString * fromText;
// and implement it in your .m file like this
-(void)initWithText:(NSString *)text
{
self = [super init];
if (self)
{
fromText = text;
}
return self;
}
// Or, you could do this.
// In ViewControllerB.h, create a property
@property (nonatomic, strong) NSString * fromText;
// In ViewControllerB.m, synthesize it
@synthesize fromText;
// Then you can pass that property a value like this
ViewControllerB * VCB = [[ViewControllerB alloc] init];
VCB.fromText = from;
回答by Hermann Klecker
Variables shoudl be lower case.
变量应该是小写的。
Your ViewControllerB should be displaed. Do you create all view elements in there programatically too? If you don't then you better load it from a XIB or from the storyboard. You can do that without segueing to it.
您的 ViewControllerB 应该被显示。您是否也以编程方式在其中创建所有视图元素?如果不这样做,则最好从 XIB 或故事板加载它。你可以做到这一点,而无需坚持。
But I guess it is much easer to overwrite the perpareForSegue:
method and set the from
property there. That is what perpareForSegue is made for when you need to do some customization programatically while using storyboards for all the easy stuff.
但我想覆盖perpareForSegue:
方法并在from
那里设置属性要容易得多。这就是 perpareForSegue 的用途,当您需要以编程方式进行一些自定义,同时使用故事板处理所有简单的事情时。
回答by blackirishman
First off, you should check your code. You are pushing a viewController named CVC onto the navigation controller. I assume this is a typo.
首先,你应该检查你的代码。您正在将名为 CVC 的 viewController 推送到导航控制器上。我认为这是一个错字。
Did you override ViewControllerB "initWithNibName:bundle:" as I see you are calling init. How would the ViewController know what nib to load if you didn't?
您是否覆盖了 ViewControllerB "initWithNibName:bundle:",因为我看到您正在调用 init.d 。如果不这样做,ViewController 怎么知道要加载哪个笔尖?
Also, it is recommended that you call [super viewDidLoad] in your viewDidLoad call.
此外,建议您在 viewDidLoad 调用中调用 [super viewDidLoad]。
回答by katch
You can push views programmatically as well. You seem to do following
您也可以以编程方式推送视图。你似乎在做以下
ViewControllerB *VCB = [[ViewControllerB alloc]init];
VCB.from = from;
[self.navigationController pushViewController:CVC animated:YES];
Which means you want to push VCB and not CVC. This change should fix your problem.
You can also put a breakpoint in viewDidLoad
to verify your new ViewController is loaded.
这意味着您要推送 VCB 而不是 CVC。此更改应该可以解决您的问题。您还可以放置一个断点viewDidLoad
来验证您的新 ViewController 是否已加载。
If you are using storyboard for VCB as well, I think you should do following --
如果您也为 VCB 使用故事板,我认为您应该执行以下操作-
ViewControllerB *VCB = [self.storyboard instantiateViewControllerWithIdentifier:@"VCBIdentifier"];
ViewControllerB *VCB = [self.storyboard instantiateViewControllerWithIdentifier:@"VCBIdentifier"];
where VCBIdentifier
is the identifier to your ViewControllerB marked in Identity Inspector -> StoryBoardID.
With your current init, I think, it is creating a default viewcontroller which is blank/empty.
VCBIdentifier
在 Identity Inspector -> StoryBoardID 中标记的 ViewControllerB 的标识符在哪里。我认为,使用您当前的 init,它正在创建一个空白/空的默认视图控制器。