- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
过去几个小时我一直在搜索,但我无法弄清楚。我正在 Obj-C 中为 iOS 创建一个钛模块。该模块编译正常。我的测试项目可以看到该模块,但是,我不断收到此错误:
在 app.js 中传递给 TiVolumesliderModule 的方法 (createView) 无效
我的 app.js 包含
var VolumeSlider = require('ti.volumeslider'); //-- this works
Titanium.API.info("module is => "+VolumeSlider); //-- this works: module is => [object TiVolumesliderModule]
var volumeSlider = VolumeSlider.createView({
width: '90%',
height: 'auto',
color: '#000',
bottom: 10,
});
我的 Obj-C 文件如下。我不太熟悉 Obj-C,所以对于发布这些长文件我深表歉意。
TiVolumesliderViewProxy.h
#import "TiViewProxy.h"
@interface TiVolumesliderViewProxy : TiViewProxy {
}
@end
TiVolumesliderViewProxy.m
#import "TiVolumesliderViewProxy.h"
#import "TiVolumesliderView.h"
NSArray* sliderKeySequence;
@implementation TiVolumesliderViewProxy
-(NSArray *)keySequence
{
if (sliderKeySequence == nil)
{
sliderKeySequence = [[NSArray arrayWithObjects:@"value",nil] retain];
}
return sliderKeySequence;
}
-(UIViewAutoresizing)verifyAutoresizing:(UIViewAutoresizing)suggestedResizing
{
return suggestedResizing & ~UIViewAutoresizingFlexibleHeight;
}
USE_VIEW_FOR_VERIFY_HEIGHT
@end
TiVolumesliderView.h
#import "TiUIView.h"
#import <MediaPlayer/MediaPlayer.h>
@interface TiVolumesliderView : TiUIView<LayoutAutosizing> {
@private
MPVolumeView *sliderView;
UISlider *volumeViewSlider;
NSDate* lastTouchUp;
NSTimeInterval lastTimeInterval;
}
- (IBAction)sliderChanged:(id)sender;
@end
TiVolumesliderView.m
#import "TiVolumesliderView.h"
#import "TiVolumesliderViewProxy.h"
#import "TiApp.h"
#import "TiUtils.h"
@implementation TiVolumesliderView
-(void)dealloc
{
[volumeViewSlider removeTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged];
RELEASE_TO_NIL(sliderView);
RELEASE_TO_NIL(lastTouchUp);
[super dealloc];
}
-(MPVolumeView*)sliderView
{
if (sliderView==nil)
{
sliderView = [[MPVolumeView alloc] initWithFrame:[self bounds]];
[sliderView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
[self addSubview:sliderView];
for (UIView *view in [sliderView subviews]) {
if ([[[view class] description] isEqualToString:@"MPVolumeSlider"]) {
volumeViewSlider = (UISlider *) view;
}
}
[volumeViewSlider addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged];
lastTouchUp = [[NSDate alloc] init];
lastTimeInterval = 1.0; // Short-circuit so that we don't ignore the first fire
}
return sliderView;
}
-(BOOL)hasTouchableListener
{
// since this guy only works with touch events, we always want them
// just always return YES no matter what listeners we have registered
return YES;
}
-(void)setThumb:(id)value forState:(UIControlState)state
{
[volumeViewSlider setThumbImage:[TiUtils image:value proxy:[self proxy]] forState:state];
}
-(void)setRightTrack:(id)value forState:(UIControlState)state
{
[volumeViewSlider setMaximumTrackImage:[TiUtils stretchableImage:value proxy:[self proxy]] forState:state];
}
-(void)setLeftTrack:(id)value forState:(UIControlState)state
{
[volumeViewSlider setMinimumTrackImage:[TiUtils stretchableImage:value proxy:[self proxy]] forState:state];
}
#pragma mark View controller stuff
-(void)setThumbImage_:(id)value
{
[self setThumb:value forState:UIControlStateNormal];
}
-(void)setSelectedThumbImage_:(id)value
{
[self setThumb:value forState:UIControlStateSelected];
}
-(void)setHighlightedThumbImage_:(id)value
{
[self setThumb:value forState:UIControlStateHighlighted];
}
-(void)setDisabledThumbImage_:(id)value
{
[self setThumb:value forState:UIControlStateDisabled];
}
-(void)setLeftTrackImage_:(id)value
{
[self setLeftTrack:value forState:UIControlStateNormal];
}
-(void)setSelectedLeftTrackImage_:(id)value
{
[self setLeftTrack:value forState:UIControlStateSelected];
}
-(void)setHighlightedLeftTrackImage_:(id)value
{
[self setLeftTrack:value forState:UIControlStateHighlighted];
}
-(void)setDisabledLeftTrackImage_:(id)value
{
[self setLeftTrack:value forState:UIControlStateDisabled];
}
-(void)setRightTrackImage_:(id)value
{
[self setRightTrack:value forState:UIControlStateNormal];
}
-(void)setSelectedRightTrackImage_:(id)value
{
[self setRightTrack:value forState:UIControlStateSelected];
}
-(void)setHighlightedRightTrackImage_:(id)value
{
[self setRightTrack:value forState:UIControlStateHighlighted];
}
-(void)setDisabledRightTrackImage_:(id)value
{
[self setRightTrack:value forState:UIControlStateDisabled];
}
-(void)setValue_:(id)value withObject:(id)properties
{
CGFloat newValue = [TiUtils floatValue:value];
if (newValue > 1)
{
newValue = 1;
}
else if (newValue < 0)
{
newValue = 0;
}
BOOL animated = [TiUtils boolValue:@"animated" properties:properties def:NO];
UISlider * ourSlider = volumeViewSlider;
[ourSlider setValue:newValue animated:animated];
[[MPMusicPlayerController applicationMusicPlayer] setVolume:newValue];
[self sliderChanged:ourSlider];
}
-(void)setValue_:(id)value
{
[self setValue_:value withObject:nil];
}
-(void)setEnabled_:(id)value
{
[volumeViewSlider setEnabled:[TiUtils boolValue:value]];
}
-(CGFloat)verifyHeight:(CGFloat)suggestedHeight
{
CGSize fitSize = [[self sliderView] sizeThatFits:CGSizeZero];
return fitSize.height;
}
USE_PROXY_FOR_VERIFY_AUTORESIZING
#pragma mark Delegates
- (IBAction)sliderChanged:(id)sender
{
NSNumber * newValue = [NSNumber numberWithFloat:[(UISlider *)sender value]];
[self.proxy replaceValue:newValue forKey:@"value" notification:NO];
if ([self.proxy _hasListeners:@"change"])
{
[self.proxy fireEvent:@"change" withObject:[NSDictionary dictionaryWithObject:newValue forKey:@"value"]];
}
}
@end
TiVolumesliderModule.h
#import "TiModule.h"
#import <MediaPlayer/MediaPlayer.h>
@interface TiVolumesliderModule : TiModule
{
}
@end
TiVolumesliderModule.m
#import "TiVolumesliderModule.h"
#import "TiApp.h"
#import "TiBase.h"
#import "TiHost.h"
#import "TiUtils.h"
@implementation TiVolumesliderModule
#pragma mark Internal
// this is generated for your module, please do not change it
-(id)moduleGUID
{
return @"56141681-6e15-4783-a284-e4aa93444757";
}
// this is generated for your module, please do not change it
-(NSString*)moduleId
{
return @"ti.volumeslider";
}
#pragma mark Lifecycle
-(void)startup
{
// this method is called when the module is first loaded
// you *must* call the superclass
[super startup];
NSLog(@"[INFO] %@ loaded",self);
}
-(void)shutdown:(id)sender
{
// this method is called when the module is being unloaded
// typically this is during shutdown. make sure you don't do too
// much processing here or the app will be quit forceably
// you *must* call the superclass
[super shutdown:sender];
}
#pragma mark Cleanup
-(void)dealloc
{
// release any resources that have been retained by the module
[super dealloc];
}
#pragma mark Internal Memory Management
-(void)didReceiveMemoryWarning:(NSNotification*)notification
{
// optionally release any resources that can be dynamically
// reloaded once memory is available - such as caches
[super didReceiveMemoryWarning:notification];
}
#pragma mark Listener Notifications
-(void)_listenerAdded:(NSString *)type count:(int)count
{
if (count == 1 && [type isEqualToString:@"my_event"])
{
// the first (of potentially many) listener is being added
// for event named 'my_event'
}
}
-(void)_listenerRemoved:(NSString *)type count:(int)count
{
if (count == 0 && [type isEqualToString:@"my_event"])
{
// the last listener called for event named 'my_event' has
// been removed, we can optionally clean up any resources
// since no body is listening at this point for that event
}
}
#pragma Public APIs
-(id)example:(id)args
{
// example method
return @"hello world";
}
-(id)exampleProp
{
// example property getter
return @"hello world";
}
-(void)exampleProp:(id)value
{
// example property setter
}
-(id)moduleVersion
{
// example property getter
return @"0.1";
}
@end
最佳答案
根据以往的经验,这可能是由一些不同的原因引起的。
文件名的大小写和前缀很重要。我发现 View 和 View 代理有些不一致。确保所有内容都有此前缀:TiVolumeslider
(带有小写的 s
),后跟 Module
或 View
或 ViewProxy
。 Titanium 做了一些魔术,将 ViewProxies
与 Module
相关联,并将 View
与 ViewProxy
相关联。
接下来,确保 View 和 View 代理 .h 和 .m 文件已添加到 Xcode 项目中。在Xcode中打开TiVolumeslider.xcodeproj
,将4个 View / View 代理.h和.m文件拖到Classes
组中。它会询问您是否要将它们添加到各种目标,您可以这样做,因此保留默认设置,添加文件,然后重试。
关于ios - 钛模块开发 : Invalid method createView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21392232/
我启动了一个使用sqlite db的Titanium应用程序。我得到奇怪的数据库结果,所以只想使用FF SQLite Manager浏览数据库,但是我不确定数据库在哪里? 这是创建数据库(部分)的代码
我正在使用Titanium SDK的openCamera函数来捕获图像并将其存储到sdcard。 function captureImage() { var capturedImg;
如何在应用程序的全屏播放视频中显示youtube或位?我必须导航到一个特殊链接吗?还是有专门的API可以全屏查看它? 想法是单击“显示视频”链接,然后全屏显示视频,并获得按钮播放纱布并“完成”。单击完
抱歉,如果它看起来像个菜鸟问题,但我是钛的新手,所以有些概念对我来说很陌生。 我有一个名为entry.js的脚本,该脚本是使用require('entry.js')从details.js调用的。 现在
在 appcelerator titanium 中,是否可以在函数调用中设置事件监听器? 有点像 var coolManDool = function(){...}; coolManDool.addE
我使用forwardGeocoder 获取纬度值,并将获得的纬度值与十进制数相加。看看下面的代码。 Ti.Geolocation.forwardGeocoder(textField.value, fu
在我看来,这个问题更接近commonJs,而不是titanium。我编写了一个大文件。相当丑陋(代码的第一次和平)。如果你愿意的话,你可以跳过它。 问题:我的代码中有 2 个 View ,我想将它们放
在 appcelerator titanium 中,是否可以在函数调用中设置事件监听器? 有点像 var coolManDool = function(){...}; coolManDool.addE
我已经为我的应用程序实现了后台服务。我正在使用它来通过使用位置服务来获取用户的当前位置。 我将解释实现此方法的方式-“XYZ.js”-显示用户距离的屏幕。添加了以下代码以设置注册后台服务- var i
我已经设置了相关的证书和应用程序,但是当我为iTunes构建它时,它将始终构建该应用程序的开发版本。我试图通过执行以下操作来更改证书: Titanium iOS设备->管理配置,但无法选择我的生产证书
是否可以在窗口加载后立即显示警报? 我有一个创建窗口语句,然后是一条警告消息,然后返回。 function NewView() { var self = Ti.UI.createWindow(
我想知道是否有一个功能可以在用户退出应用程序时保存上次查看的窗口,这样当他们再次进入应用程序时,它会转到上次查看的页面,而不是重新启动。我看过 Ti.App.Properties,但还没有真正找到我要
我可以在单个 Controller 文件中做到这一点: Ti.Network.addEventListener('change', function(e) { networkIsOnline
我是 Titanium Studio 的初学者。选择按钮时我可以隐藏键盘。它有效, okBtn.addEventListener("click", function(e) { textField.bl
我正在使用 Titan 创建一个适用于 Android 和 iOS 的应用程序,只要服务器运行,它就会每 5 秒向服务器发送一个新的地理位置。然而,在 iOS 上,应用程序会在随机间隔后停止发送这些位
我在 ScrollView 中有两个 View ,它们是使用垂直布局属性放置的。我尝试了多种组合,但两种 View 之间总是存在巨大差距。 var view = Titanium.UI.createS
我可以将其关闭。 代码: //get current Location // Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY
如何在 XML 中制作网格布局。例如说我想要一个 4x4 板。我只需要制作 16 个按钮并使用 jss 格式化它们吗?例如,这就是我所拥有的,但还不是板格式。 square
这是我第一次为 iPhone 开发钛金属模块。我正在为 iPhone 构建 Google Analytics 模块。 如果我要使用 XCode 实现 Google Analytics,我可以使用 di
有没有一种方法可以用 javascript(使用 titanium)计算 PDF 页数?我正在开发一个应用程序,我需要页面数量才能知道用户在哪个页面上。现在我正在对大量页面进行硬编码,但我想通过 ja
我是一名优秀的程序员,十分优秀!