MFMessageComposeVIewController忽略它的委托,而不是它本身(MFMessageComposeVIewController is dismissing its delegate instead of itself)
我有一个符合MFMessageComposeViewControllerDelegate协议的VC。
我用下面的代码成功地展示了这个视图控制器:
- (IBAction)textAction:(id)sender { if(![MFMessageComposeViewController canSendText]) { UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Your device doesn't support SMS!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [warningAlert show]; return; } NSString *numberToCallOrText = self.phoneNumber; NSString *message = @"Test message"; NSArray *recipients = [NSArray arrayWithObject:numberToCallOrText]; MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init]; messageController.messageComposeDelegate = self; [messageController setRecipients:recipients]; [messageController setBody:message]; // Present message view controller on screen [self.view endEditing:YES]; [self presentViewController:messageController animated:YES completion:nil]; }
另外,我正在处理完成结果,如下所示:
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result { switch (result) { case MessageComposeResultCancelled: NSLog(@"Canceled"); break; case MessageComposeResultFailed: { NSLog(@"Failed"); UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to send SMS!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [warningAlert show]; break; } case MessageComposeResultSent: NSLog(@"sent"); [self.navigationController popViewControllerAnimated:YES]; break; default: break; } [controller.view endEditing:YES]; [self.navigationController popViewControllerAnimated:YES]; // [self dismissViewControllerAnimated:YES completion:nil]; // [controller popToViewController:self animated:YES]; // [controller dismissViewControllerAnimated:YES completion:nil]; }
三条注释掉的线是我尝试过的替代品。 发生的事情是MFMessageComposeViewController保留在屏幕上(虽然键盘被解除),但是委托从堆栈中弹出。 因此,当我再次点击取消时,我得到一个空引用错误。
这很奇怪,因为这个相同的实现在我的代码中的其他地方工作。 唯一的区别是我已经设置了要初始化的主体。
任何想法为什么错误的VC会在这里突然出现?
谢谢。
编辑 - 破坏的实现是在UITableViewController而不是UIView控制器...可能是什么导致了问题?
I have a VC that conforms to the MFMessageComposeViewControllerDelegate protocol.
I am successfully presenting this view controller with the following code:
- (IBAction)textAction:(id)sender { if(![MFMessageComposeViewController canSendText]) { UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Your device doesn't support SMS!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [warningAlert show]; return; } NSString *numberToCallOrText = self.phoneNumber; NSString *message = @"Test message"; NSArray *recipients = [NSArray arrayWithObject:numberToCallOrText]; MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init]; messageController.messageComposeDelegate = self; [messageController setRecipients:recipients]; [messageController setBody:message]; // Present message view controller on screen [self.view endEditing:YES]; [self presentViewController:messageController animated:YES completion:nil]; }
Additionally, I am handling the finish result like so:
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result { switch (result) { case MessageComposeResultCancelled: NSLog(@"Canceled"); break; case MessageComposeResultFailed: { NSLog(@"Failed"); UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to send SMS!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [warningAlert show]; break; } case MessageComposeResultSent: NSLog(@"sent"); [self.navigationController popViewControllerAnimated:YES]; break; default: break; } [controller.view endEditing:YES]; [self.navigationController popViewControllerAnimated:YES]; // [self dismissViewControllerAnimated:YES completion:nil]; // [controller popToViewController:self animated:YES]; // [controller dismissViewControllerAnimated:YES completion:nil]; }
The three commented out lines are alternatives that I have tried. What's happening is that the MFMessageComposeViewController is remaining on the screen (though the keyboard is dismissed), but the delegate is being popped from the stack. Therefore, when I hit cancel again, I get a null reference error.
It's odd, because this same implementation works elsewhere in my code. The only difference is that I've set the body to be initialized.
Any ideas why the wrong VC is getting popped here?
Thanks.
Edit - The broken implementation is on a UITableViewController rather than UIView Controller... could that be what is causing the problem?
原文:https://stackoverflow.com/questions/40389457
最满意答案
我一开始努力让搜索字段在MVC风格的应用程序中工作。
我能够在你的sencha小提琴应用程序中使搜索字段工作。
在你的控制器中我做到了
Ext.define('Sencha.controller.Main', { extend: 'Ext.app.Controller', config: { refs: { main: 'mainpanel' }, control: { '#list': { disclose: 'showDetail' }, '#view':{ activate:function(){ Ext.getCmp('list').add({ xtype:'toolbar', docked:'top', items:[{ xtype: 'searchfield', itemId:'contact_search', placeHolder: 'Search....', listeners: { scope: this, clearicontap: this.onSearchClearIconTap, keyup: this.onSearchKeyUp} }] }) } } } }, showDetail: function(list, record) { this.getMain().push({ xtype: 'recipedetail', title: record.fullName(), data: record.data }) }, onSearchKeyUp: function(field) { //get the store and the value of the field var value = field.getValue(), store = Ext.getCmp('list').getStore(); //first clear any current filters on thes tore store.clearFilter(); //check if a value is set first, as if it isnt we dont have to do anything if (value) { //the user could have entered spaces, so we must split them so we can loop through them all var searches = value.split(' '), regexps = [], i; //loop them all for (i = 0; i < searches.length; i++) { //if it is nothing, continue if (!searches[i]) continue; //if found, create a new regular expression which is case insenstive regexps.push(new RegExp(searches[i], 'i')); } //now filter the store by passing a method //the passed method will be called for each record in the store store.filter(function(record) { var matched = []; //loop through each of the regular expressions for (i = 0; i < regexps.length; i++) { var search = regexps[i], didMatch = record.get('title').match(search); //if it matched the first or last name, push it into the matches array matched.push(didMatch); } //if nothing was found, return false (dont so in the store) if (regexps.length > 1 && matched.indexOf(false) != -1) { return false; } else { //else true true (show in the store) return matched[0]; } }); } }, /** * Called when the user taps on the clear icon in the search field. * It simply removes the filter form the store */ onSearchClearIconTap: function() { //call the clearFilter method on the store instance this.getStore().clearFilter(); } });
然后在app.js中我向视口添加了一个ID
launch: function() { Ext.Viewport.add({ id:'view', xtype: 'mainpanel' }); }
我还在RecieptList.js中添加了一个ID
xtype: 'recipelist', requires: ['Sencha.store.Recipes'], id:'list', config: {
可能不是最传统的解决方案,但它的工作原理。 很容易看出它们如何一起工作,希望有所帮助。
I struggled with getting the search field to work in an MVC style app at first.
I was able to make a search field work in your sencha fiddle app like this.
In your controller I did
Ext.define('Sencha.controller.Main', { extend: 'Ext.app.Controller', config: { refs: { main: 'mainpanel' }, control: { '#list': { disclose: 'showDetail' }, '#view':{ activate:function(){ Ext.getCmp('list').add({ xtype:'toolbar', docked:'top', items:[{ xtype: 'searchfield', itemId:'contact_search', placeHolder: 'Search....', listeners: { scope: this, clearicontap: this.onSearchClearIconTap, keyup: this.onSearchKeyUp} }] }) } } } }, showDetail: function(list, record) { this.getMain().push({ xtype: 'recipedetail', title: record.fullName(), data: record.data }) }, onSearchKeyUp: function(field) { //get the store and the value of the field var value = field.getValue(), store = Ext.getCmp('list').getStore(); //first clear any current filters on thes tore store.clearFilter(); //check if a value is set first, as if it isnt we dont have to do anything if (value) { //the user could have entered spaces, so we must split them so we can loop through them all var searches = value.split(' '), regexps = [], i; //loop them all for (i = 0; i < searches.length; i++) { //if it is nothing, continue if (!searches[i]) continue; //if found, create a new regular expression which is case insenstive regexps.push(new RegExp(searches[i], 'i')); } //now filter the store by passing a method //the passed method will be called for each record in the store store.filter(function(record) { var matched = []; //loop through each of the regular expressions for (i = 0; i < regexps.length; i++) { var search = regexps[i], didMatch = record.get('title').match(search); //if it matched the first or last name, push it into the matches array matched.push(didMatch); } //if nothing was found, return false (dont so in the store) if (regexps.length > 1 && matched.indexOf(false) != -1) { return false; } else { //else true true (show in the store) return matched[0]; } }); } }, /** * Called when the user taps on the clear icon in the search field. * It simply removes the filter form the store */ onSearchClearIconTap: function() { //call the clearFilter method on the store instance this.getStore().clearFilter(); } });
And then in the app.js I added an ID to the viewport
launch: function() { Ext.Viewport.add({ id:'view', xtype: 'mainpanel' }); }
I also added an ID to the RecieptList.js
xtype: 'recipelist', requires: ['Sencha.store.Recipes'], id:'list', config: {
Might not be the most conventional solution but it works. It is pretty easy to see how it all works together, hope that helps.
相关问答
更多-
Sencha Touch 2.3:将数据从列表视图推送到详细视图(Sencha Touch 2.3: Pushing data from list view to detail view)[2024-03-18]
你是绝对正确的。 您没有设置嵌套面板的数据,而是设置Prac.view.Detail的数据。 数据是面板的配置属性。 这意味着sencha将为您创建一个setData()方法。 当您在内部使用此方法时,将分别updateData() applyData()或updateData() 。 在你的情况下,这应该工作: Ext.define('Prac.view.Detail', { extend: 'Ext.Panel', xtype: 'detail', config: { ... -
AFAIK如果您正在寻找要显示的项目数组,您应该使用商店中的项目模型和指向项目的rootProperty Ext.define('senchaHackerNews.store.Search', { extend: 'Ext.data.Store', requires: ['senchaHackerNews.model.SearchResults'], config: { storeId: 'hnSearchStore', model: 'sencha ...
-
undefined来自这一行: Ext.ComponentQuery.query('#offersListHomeView')[0].update(); 更新是decrapted(我写了,因为我用旧的Sencha Touch版本开发一次并且这个更新是必要的)并且将调用setHtml(),因为我们没有传递任何参数它是设置“undefined”,这将显示在我们的观点。 在新的sencha版本中,您只需删除此行即可。 我还在控制器中使用此代码管理了全局存储问题: launch: function() { ...
-
正如@Jimmy所提到的,列表中没有onLoad方法。 但是,有几种方法可以解决它。 我对你想要实现的内容的理解是,当加载支持列表的存储时,你希望从ProductList实例(而不是list )触发事件,这样在控制器中你可以将control配置为: control: { ProductList: { productListSelectedCommand: 'productListSelectCommand', productListLoadedCommand: 'pr ...
-
我不确定,但您应该在Person详细信息视图中使用以下代码: items: [ { xtype:'formpanel', id:'personDetailViewForm', items:[{ xtype: 'fieldset', items: [{ xtype: 'textfield', name: 'n ...
-
Sencha touch,选择主对象项目时显示详细信息(Sencha touch, Show details when selecting master objects' item)[2021-09-30]
你想要的教程在这里: http://docs-origin.sencha.com/touch/2.3.0/#!/guide/first_app 专注于“博客”功能。 它遵循主要细节模式。 关于您的申请,我不知道,因为您没有上传任何相关的源代码。 The tutorial you want is here: http://docs-origin.sencha.com/touch/2.3.0/#!/guide/first_app Stay focus on the "Blog" features. It fol ... -
我想您需要搜索字段的搜索功能..在键入时显示结果。 您可以通过使用正则表达式并将它们与商店中的条目进行比较来实现此目的。 这是我在项目中使用的代码: //referencing my searchfield Search: '#searchfield'; //attaching an event Search: { keyup: "OnFocus" } //the actual function OnFocus: funct ...
-
我一开始努力让搜索字段在MVC风格的应用程序中工作。 我能够在你的sencha小提琴应用程序中使搜索字段工作。 在你的控制器中我做到了 Ext.define('Sencha.controller.Main', { extend: 'Ext.app.Controller', config: { refs: { main: 'mainpanel' }, control: { '#list': { ...
-
嘿@GordanWebb尝试从XML文件中显示数据, Ext.regModel('Personal', { fields : [ 'id', {name: 'name', type: 'string'}, {name: 'email', type: 'string'} ] }), { scroll : 'vertical', items : [ { ...
-
您可以在模板中使用内联javascript代码来分割坐标变量。 以下是文档中的示例: var tpl = new Ext.XTemplate( '
Name: {name}
', 'Company: {[values.company.toUpperCase() + ", " + values.title]}
', 'Kids: ', '
', ' 相关文章
更多- 忽略特殊文件-git入门教程
- HttpClient 获取HTTPS证书和忽略证书错误
- 微信收费事件背后被广泛忽略的技术细节
- 微信收费事件背后被广泛忽略的技术细节
- SolrCloud分布式检索时忽略宕机的Shard
- 实现友盟分享
- solr dataimport 数据导入源码分析(五)
- 友盟分享到朋友圈时, 点击链接跳转到友盟自家页面的处理
- Storm-源码分析- bolt (backtype.storm.task)
- 设计模式之代理模式(静态代理和动态代理)
最新问答
更多- 在ios 7中的UITableView部分周围绘制边界线(draw borderline around UITableView section in ios 7)
- Java中的不可变类(Immutable class in Java)
- 寻求多次出现的表达式(Seeking for more than one occurrence of an expression)
- linux只知道文件名,不知道在哪个目录,怎么找到文件所在目录
- Actionscript:检查字符串是否包含域或子域(Actionscript: check if string contains domain or subdomain)
- 懒惰地初始化AutoMapper(Lazily initializing AutoMapper)
- 使用hasclass为多个div与一个按钮问题(using hasclass for multiple divs with one button Problems)
- Windows Phone 7:检查资源是否存在(Windows Phone 7: Check If Resource Exists)
- EXCEL VBA 基础教程下载
- RoR - 邮件中的动态主体(部分)(RoR - Dynamic body (part) in mailer)
- 无法在Google Script中返回2D数组?(Can not return 2D Array in Google Script?)
- JAVA环境变量的设置和对path , classpth ,java_home设置作用和目的?
- mysql 关于分组查询、时间条件查询
- 如何使用PowerShell匹配运算符(How to use the PowerShell match operator)
- Effective C ++,第三版:重载const函数(Effective C++, Third edition: Overloading const function)
- 如何用DELPHI动态建立MYSQL的数据库和表? 请示出源代码。谢谢!
- 带有简单redis应用程序的Node.js抛出“未处理的错误”(Node.js with simple redis application throwing 'unhandled error')
- 使用前端框架带来哪些好处,相对于使用jquery
- Ruby将字符串($ 100.99)转换为float或BigDecimal(Ruby convert string ($100.99) to float or BigDecimal)
- 高考完可以去做些什么?注意什么?
- 如何声明放在main之后的类模板?(How do I declare a class template that is placed after the main?)
- 如何使用XSLT基于兄弟姐妹对元素进行分组(How to group elements based on their siblings using XSLT)
- 在wordpress中的所有页面的标志(Logo in all pages in wordpress)
- R:使用rollapply对列组进行求和的问题(R: Problems using rollapply to sum groups of columns)
- Allauth不会保存其他字段(Allauth will not save additional fields)
- python中使用sys模块中sys.exit()好像不能退出?
- 将Int拆分为3个字节并返回C语言(Splitting an Int to 3 bytes and back in C)
- 在SD / MMC中启用DDR会导致问题吗?(Enabling DDR in SD/MMC causes problems? CMD 11 gives a response but the voltage switch wont complete)
- sed没有按预期工作,从字符串中间删除特殊字符(sed not working as expected, removing special character from middle of string)
- 如何将字符串转换为Elixir中的函数(how to convert a string to a function in Elixir)