Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/97.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 未解除分配带有inputAccessoryView的UIViewController_Ios_Objective C_Ios7_Uiviewcontroller_Uiresponder - Fatal编程技术网

Ios 未解除分配带有inputAccessoryView的UIViewController

Ios 未解除分配带有inputAccessoryView的UIViewController,ios,objective-c,ios7,uiviewcontroller,uiresponder,Ios,Objective C,Ios7,Uiviewcontroller,Uiresponder,我有一个简单的UIViewController子类(代码如下)。 如果我附加inputAccessoryView,我的viewcontroller永远不会解除分配。如果我没有在viewDidLoad中设置inputAccessoryView,将按预期调用dealloc 我错过什么了吗 @interface IMTestViewController : UIViewController @property (nonatomic, strong) UIView *messageInputView;

我有一个简单的UIViewController子类(代码如下)。 如果我附加inputAccessoryView,我的viewcontroller永远不会解除分配。如果我没有在viewDidLoad中设置inputAccessoryView,将按预期调用dealloc

我错过什么了吗

@interface IMTestViewController : UIViewController

@property (nonatomic, strong) UIView *messageInputView;
@property(nonatomic, readwrite, strong) UIView *inputAccessoryView;

@end

@implementation IMTestViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)dealloc
{

}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.inputAccessoryView = self.messageInputView;
}

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

- (UIView *)messageInputView
{
    if (_messageInputView == nil)
    {
        _messageInputView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 45)];
        _messageInputView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    }
    return _messageInputView;
}
@end
我已经没有主意了。
谢谢。

不幸的是@rdelmar的回答不起作用。经过一段时间的尝试,我发现了这篇文章:

我的目标是让输入附件视图可见,即使键盘不可见,与所有IM应用程序完全相同。我之前对我的
UIViewController
自定义类进行了子类化,以允许它成为第一响应者,并将自定义子视图返回为
inputAccessoryView
。这会阻止解除分配视图控制器。现在我对控制器的视图进行子类化,以实现上面链接中推荐的相同功能,一切似乎都很好

编辑:经过更多的测试,我可以确认自定义UIView被解除分配了


编辑2:唯一的缺点是你不能让键盘出现在
视图中,而
inputAccessoryView
尚未添加到视图层次结构中,无法成为第一响应者。

这个问题很老了,但我在2019年尝试在iOS 12中使用inputAccessoryView时遇到了它

解除分配问题今天仍然存在,中提到的文章中提出的第一个解决方案也不起作用。本文中的第二个解决方案(涉及动画)工作量太大,当用户通过带有
scrollView.keyboardDismissMode=.interactive的UIScrollView交互关闭键盘时,效果不佳

我能想到的最好方法就是在
viewdiddefine
上将第一响应者
UITextField
UITextView
inputAccessoryView
设置为
nil
。这完全消除了内存泄漏,并且似乎没有任何副作用或缺点

下面是一个完整的Swift 4.2示例:

class MyViewController: UIViewController {
    /// You could also add your text field or text view programmatically, 
    /// but let's say it's coming from a .xib for now...
    @IBOutlet private weak var myTextField: UITextField!

    /// This is required for the inputAccessoryView to work.
    override internal var canBecomeFirstResponder: Bool {
        return true
    }

    /// Here's a nice empty red view that will be used as an
    /// input accessory.
    private lazy var accessoryView: UIView = {
        let accessoryView = UIView()
        accessoryView.backgroundColor = UIColor.red
        accessoryView.frame.size = CGSize(
            width: view.frame.size.width,
            height: 45
        )

        return accessoryView
    } ()

    override var inputAccessoryView: UIView? {
        return accessoryView
    }

    /// This is required to avoid leaking the `inputAccessoryView`
    /// when the keyboard is open and the `UIViewController`
    /// is deallocated.
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        myTextField.inputAccessoryView = nil
    }
}

是否要将此inputAccessoryView添加到显示的键盘?如果是这样的话,说明你做得不对。inputAccessoryView是UITextField上的属性,而不是UIViewController。我不确定,为什么这样做会导致控制器无法释放,但如果您将名称更改为inputAccessoryView以外的名称,则会正确释放控制器。因此,似乎不正确地使用此属性名称会使系统混淆。请添加用于设置
self.messageInputView
的代码和用于显示
IMTestViewController
@rdelmar,inputAccessoryView是UIResponder的属性,UIResponder是UIViewController的超类。@Rafeek,这是我所有的代码。我为此创建了一个示例项目。appDelegate中的代码:UINavigationController*nav=[[UINavigationController alloc]initWithRootViewController:[UIViewController new]];[nav pushViewController:[IMChatIAVViewController new]已设置动画:否];self.window.rootViewController=nav;我和你在同一点上。如果您找到了解决方案,请告诉我。哇,让视图成为响应者而不是视图控制器本身是个好主意。它解决了分配问题。非常感谢。这是一个伟大的发现,我一直在寻找解决方案已经有一段时间了。在iOS>7上,UIViewController子类工作正常,但文章中提到的inputAccessoryView的内存泄漏仍然存在:(是的,如果我的答案不太清楚,很抱歉。我过去常返回视图控制器,但现在我将其视图子类化,以使其成为第一响应者。我认为这是最简单的,但可能在中执行此操作时确实消失了,因为在使用UINavigationController的交互式弹出手势时可以调用WillEngase,该手势可以取消d、 另外,当显示另一个viewController时,viewController可能会消失,因此可以检查presentedViewController==nil@dkvch呜呜!!你说得完全对!我以为那就是我输入的:)我现在就修复它。谢谢!关于控制器的消失,我认为这无关紧要,因为将再次调用
inputAccessoryView
。您只需确保视图在此期间没有被解除分配(在本例中,它不是-因为在private lazy var中有对它的强烈引用)。