警告:尝试显示其视图不在窗口层次结构中的*

时间:2014-06-27 17:47:40

标签: ios iphone objective-c cocoa-touch

首先,我要感谢你们所有人! :)

所以,我有一个带有表格视图的主视图控制器,以及来自另一个类的自定义单元格。我已经自定义选择单元格(您必须滑动视图的单元格)。在那个动作中,我在主视图控制器中调用方法发送短信。但我收到此警告,并且SMS控制器没有出现。我知道,这个错误信息意味着,它无法打开SMS控制器,因为主控制器没有加载?我从这里尝试了一些代码,但没有什么对我有用。我的班级目前看起来像这样:

Main controller.m

.
.
.

-(void)viewWillAppear:(BOOL)animated
{
    [self.citiesButton setTitle:rowValue forState:UIControlStateNormal];

    UITableView *tableView = (id)[self.view viewWithTag:1];
{
    tableView.rowHeight = 100;
    UINib *nib  = [UINib nibWithNibName:@"TableViewCell" bundle:nil];
    [tableView registerNib:nib forCellReuseIdentifier:CellTableIdentifier];

    UIEdgeInsets contentInset = tableView.contentInset;
    contentInset.top = 20;
    [tableView setContentInset:contentInset];

    NSLog(@"rowValue is %@", rowValue);
    self.city = [_dict objectForKey:rowValue];
}

    NSLog(@"View will appear");
    [tableView reloadData];
}

-(void)sendSMS
{
    MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
    if([MFMessageComposeViewController canSendText])

    {
        controller.body = @"Testy Test";
        controller.recipients = [NSArray arrayWithObjects:@"774252704", nil];
        controller.messageComposeDelegate = self;

        [self dismissViewControllerAnimated:YES completion:^{
        [self presentViewController:controller animated:YES completion:nil];
    }];

}
}

所以我试图首先关闭主控制器,然后显示smsController,但仍然没有运气。我认为,问题在于我从TableViewCell类调用方法,但是,在加载视图后创建表,所以我真的迷失在这里。

非常感谢你的时间!

===== EDIT =====

这是自定义单元格类,我将其称为sendSMS方法

tableViewCell.m

#import "TableViewCell.h"
#import "TableViewController.h"

static NSString *CellTableIdentifier = @"TableViewCell";

@implementation TableViewCell

@synthesize timeLabel = _timeLabel;
@synthesize priceLabel = _priceLabel;
@synthesize infoLabel = _infoLabel;


- (void)awakeFromNib
{
    // Initialization code
}


-(void)layoutSubviews
{
    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureRecognizer:)];

    [self addGestureRecognizer:panGesture];
}


-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {

    self = [super initWithStyle:style reuseIdentifier:CellTableIdentifier];



    return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

-(void)panGestureRecognizer:(UIPanGestureRecognizer *)sender{
    CGPoint translation = [sender translationInView:self];

    TableViewController *mainController = [[TableViewController alloc] init];

    //NSLog(@"Panned with translation point: %@", NSStringFromCGPoint(translation));

    sender.view.center = CGPointMake(sender.view.center.x + translation.x,
                                 sender.view.center.y);


    CGPoint breakingPoint = CGPointMake(320,sender.view.center.y);
    CGPoint startPoint = CGPointMake(150, sender.view.center.y);
    CGPoint endPoint = CGPointMake(500, sender.view.center.y);

    if (sender.view.center.x <= startPoint.x) {
        sender.view.center = startPoint;
    }

    if (sender.state == UIGestureRecognizerStateEnded) {
        if (sender.view.center.x >= breakingPoint.x) {

            [UIView animateWithDuration:0.2
                              delay:0.0
                            options: UIViewAnimationOptionCurveEaseOut
                         animations:^{
                             sender.view.center = endPoint;
                         }
                         completion:^(BOOL finished){
                             NSLog(@"Bought!");
                             [mainController sendSMS];
                         }];

    } else {
        //recognizer.view.center = startPoint;

        [UIView animateWithDuration:0.2
                              delay:0.0
                            options: UIViewAnimationOptionCurveEaseOut
                         animations:^{
                             sender.view.center = startPoint;
                         }
                         completion:^(BOOL finished){
                             NSLog(@"Returned!");
                         }];
    }
}
    [sender setTranslation: CGPointZero inView: self];
}

2 个答案:

答案 0 :(得分:1)

我的猜测基于描述(如果我理解你的代码正确)是你解雇mainViewController,然后它就去了它以呈现视图控制器。由于它已被解雇,因此不允许提供任何内容。

就像当女童子军来到你家里送你的饼干时,你告诉他们&#34;回到家里,不要回来,当你回到家时,把我的饼干留在我家里前门。&#34;

尝试移动解散mainViewController的代码,然后将新控制器呈现给最初呈现mainViewController的视图控制器。

编辑:

我在UITableviewCell类中发现了另一个错误。问题是这一行,位于你的panGestureRecognizer函数中。

TableViewController *mainController = [[TableViewController alloc] init];

您创建一个mainController实例,然后在几行之后调用

[mainController sendSMS];

这是尝试呈现视图控制器,但是mainController的实例从未被推送到视图堆栈,因此出错。

您需要做的是在tableviewController实例上调用sendSMS,该实例是保存tableview的实例,因此是tableViewCell。下面是另一篇文章,讨论如何做到这一点Reference from UITableViewCell to UITableView to UINavigationController

答案 1 :(得分:1)

- (void)presentViewController:(UIViewController *)viewController animated:(BOOL)animated onComplete:(void (^)(void))callback
{
    AppDelegate *APP_DELEGATE = [UIApplication sharedApplication].delegate;

    UIViewController *presentedModalVC = [APP_DELEGATE.window.rootViewController presentedViewController];

    if (presentedModalVC) {
        while (presentedModalVC.presentedViewController) {
            presentedModalVC = presentedModalVC.presentedViewController;
        }
        [presentedModalVC presentViewController:viewController animated:animated completion:callback];
    } else {
        [APP_DELEGATE.window.rootViewController presentViewController:viewController animated:animated completion:callback];
    }
}

-(void)sendSMS
{
    MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
    if([MFMessageComposeViewController canSendText])

    {
        controller.body = @"Testy Test";
        controller.recipients = [NSArray arrayWithObjects:@"774252704", nil];
        controller.messageComposeDelegate = self;

        [self presentViewController:controller animated:YES onComplete:nil];
    }              
}

您必须在当前呈现的vc上显示您的vc,如果存在,即如果您具有此vc的层次结构

VC1---  
  VC2 - presented by VC1-----  
    VC3 - presented by VS2----  
...  
      VCx - presented by x-1 

然后你必须在VCx上展示你的新vc,即在当前呈现/可见的最后一个vc上。