只是试图在某些情况下围绕ReactiveCocoa方法.
我有一种情况,即段控制器交换子视图控制器.我需要在这里做几件事:
contentInset,tableView因为iOS7没有为我自己处理自定义容器视图contentInset带动画navigationBar后退并重置contentInset动画以下是以命令式样式完成此操作的当前代码:
- (void)didMoveToParentViewController:(UIViewController *)parent
{
[super didMoveToParentViewController:parent];
if (parent) {
CGFloat top = parent.topLayoutGuide.length;
CGFloat bottom = parent.bottomLayoutGuide.length;
if (self.tableView.contentInset.top != top) {
UIEdgeInsets newInsets = UIEdgeInsetsMake(top, 0, bottom, 0);
self.tableView.contentInset = newInsets;
self.tableView.scrollIndicatorInsets = newInsets;
}
}
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
[UIView animateWithDuration:.25 animations:^{
self.navigationController.navigationBar.alpha=0;
self.tableView.contentInset = UIEdgeInsetsMake([UIApplication sharedApplication].statusBarFrame.size.height, 0, 0, 0);
}];
return YES;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
[UIView animateWithDuration:.25 animations:^{ …Run Code Online (Sandbox Code Playgroud) 出于某种原因,我没有收到错误消息.(我在这里简化了代码以直截了当.)
// Send an error message
_loginButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendError:error]; // Pretend this is a real error
return nil;
}];
}];
// Subscribe to loginButton's returned signal
[_loginButton.rac_command.executionSignals subscribeNext:^(RACSignal *loginSignal) {
[loginSignal subscribeError:^(NSError *error) {
NSLog(@"A");
} completed:^{
NSLog(@"B");
}];
}];
Run Code Online (Sandbox Code Playgroud)
这打印"B".知道为什么吗?如果-sendError:在订户上调用,为什么完成块会收到它?
我正在实现一个聊天UI,并使用Reactive Cocoa根据用户的类型调整聊天气泡的大小.目前,我正在根据textview更新UI的布局rac_textSignal.一切都很好 - 除了一点:当用户发送消息时,我以编程方式清除文本字段:
_inputTextView.text = @"";
Run Code Online (Sandbox Code Playgroud)
...但textview rac_textSignal不会激活.我听说这是ReactiveCocoa的一个功能 - 但是构建它的正确方法是什么?我是否需要拥有一个NSString currentlyTypedString,并在该字符串更新时驱动UI更改?
(也可以在GitHub上公开评论来自ReactiveCocoa的人.)
我在一个非常简单的尝试ReactiveCocoa RACTest(源是在GitHub上)应用程序试图通过实际使用它坚定了我的理论认识.
我想,我有一个RACChannel,它提供了一个ed l值和我指定的任何参数之间的双向绑定.RAC()RACChannel
我的用法如下:
// Map the ticker's accumulationEnabled property to self.paused.
RAC(self, paused) = [RACChannelTo(_ticker, accumulateEnabled) deliverOn:[RACScheduler mainThreadScheduler]];
Run Code Online (Sandbox Code Playgroud)
我看到流动的变化的一个方向,从_ticker.accumulateEnabled到self.paused,但变化self.paused不会流回_ticker.
我误解了RACChannel吗?它有什么用,这怎么不是预期的用途?
我的任务是为应用程序添加一些检测逻辑,以跟踪各种API调用的延迟.我正在努力想出一种干净的,无副作用的方法来为返回RACSignal(延迟执行API调用)的方法添加时序检测.
completed活动时记录时间我唯一能想到的就是创建一个处理定时器逻辑的具体RACSubscriber子类.除了令人讨厌的子类,这显然不是理想的,因为它需要一个显式subscribe:,这反过来需要一个replay源信号.此外,调用者还有一个负担,因为他们必须至少重构以获得信号的临时句柄.
@interface SignalTimer : RACSubscriber
@property (nonatomic) NSDate *startDate;
@end
@implementation SignalTimer
- (void)didSubscribeWithDisposable:(RACDisposable *)disposable
{
[super didSubscribeWithDisposable:disposable];
self.startDate = [NSDate date];
}
- (void)sendCompleted
{
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:self.startDate];
NSLog(@"Time elapsed: %f", duration);
[super sendCompleted];
}
@end
Run Code Online (Sandbox Code Playgroud)
用法如下所示:
- (RACSignal*)saveFoo:(Foo*)fooParseObj {
RACSignal *save = [[fooParseObj rac_save] replay]; // Don't forget replay!
[save subscribe:[[SignalTimer alloc] initWithName@"Saving the user's foo …Run Code Online (Sandbox Code Playgroud) 我正在使用ReactiveCocoa信号来表示对我们系统中RESTful后端的调用.每个RESTful调用都应该接收一个令牌作为参数之一.令牌本身是从身份验证API调用接收的.
所有工作正常,我们现在介绍令牌到期,所以后端接入类可能需要如果API调用失败,HTTP代码403我想使这个操作的调用者完全透明的重新授权本身,这是我来最好起来:
- (RACSignal *)apiCallWithSession:(Session *)session base:(NSString *)base params:(NSDictionary *)params get:(BOOL)get {
NSMutableDictionary* p = [params mutableCopy];
p[@"token"] = session.token;
RACSubject *subject = [RACReplaySubject subject];
RACSignal *first = [self apiCall:base params:p get:get]; // this returns the signal representing the asynchronous HTTP operation
@weakify(self);
[first subscribeNext:^(id x) {
[subject sendNext:x]; // if it works, all is fine
} error:^(NSError *error) {
@strongify(self);
// if it doesn't work, try re-requesting a token
RACSignal *f = [[self action:@"logon" email:session.user.email password:session.user.password]
flattenMap:^RACStream *(NSDictionary *json) …Run Code Online (Sandbox Code Playgroud) 我正在尝试观察我的ViewModel中的属性,然后使用ReactiveCocoa更新带有它的值的标签,但它没有更新.
这是我得到的:
视图模型
var amount: NSDecimalNumber
Run Code Online (Sandbox Code Playgroud)
视图控制器
RAC(self.amountLabel, "text") <~ RACObserve(self.viewModel, "amount").map({
(value) -> AnyObject! in
let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = .CurrencyStyle
return numberFormatter.stringFromNumber(value as NSDecimalNumber)
})
Run Code Online (Sandbox Code Playgroud)
我检查过,ViewModel正在更新'amount'属性.这里有什么我想念的吗?
我也试过这个测试:
RACObserve(self.viewModel, "amount").subscribeNext {
(value) -> Void in
println(value)
}
Run Code Online (Sandbox Code Playgroud)
也不起作用.
我正在使用ReactiveCocoa 2.4.7,因为我的应用程序支持iOS 7. Swift [1,2]和此版本中的宏替换之间是否存在任何不兼容性?
[1] - https://github.com/ashfurrow/Swift-RAC-Macros
[2] - http://blog.scottlogic.com/2014/07/24/mvvm-reactivecocoa-swift.html
如何通过Signal点击来创建UIButton?
到目前为止,我试图使用目标/行动,但已经开始认为可能有一种更简单的方法.
在Colin Eberhardt的一篇文章中,声明Signals适用于UI操作.但是当我尝试使用目标/动作时,我需要创建一个CocoaAction最终初始化为SignalProducer.
我想要的是一些在每个用户点击时Signal发出它的next事件.然后,我想要将此信号转换为读取UITextFields并继续执行这些值以在我的应用程序中使用它们.
我觉得我理解ReactiveCocoa的所有基本组件(从概念上讲),通过了解如何将所有组件连接在一起仍然有点令人困惑.
例如,在阅读了有关Signal之后,我完全希望SignalProducer只有一个start()方法返回一个Signal,你可以这样使用它:
mySignalProducer.start().observe(myObserver)
Run Code Online (Sandbox Code Playgroud)
相反,你必须将观察者传递给start(),SignalProducer为你调用observe():
mySignalProducer.start(myObserver)
Run Code Online (Sandbox Code Playgroud)
这意味着SignalProducer的接口要大得多(更需要理解),因为observe()的所有变量都必须在start()上重复(例如startNext()等).
我认为这里有两种可能性:
如果是1,我猜这与内存管理和一次性用品有关,我还不完全了解.
我更担心2是这样的.在内部,我对SignalProducer的理解基本上映射到Factory的概念,例如:
mySignalFactory.createSignal().observe(myObserver)
Run Code Online (Sandbox Code Playgroud)
这就是为什么我很惊讶我们没有找到返回Signal的start().
如果社区可以在这里阐明一点,我将非常感激.
谢谢!
我实施了"反应",UIAlertController所以我可以Observable<Int>按下按钮.(见下面的代码).
我的问题或疑问是:
这是实施.我删除了与te问题无关的部分.
class AlertBuilder {
typealias AlertAction = (Int) -> ()
private let alert: UIAlertController
/** If observable() is called, we keep here the observers to notify them */
private var observers: [AnyObserver<Int>] = []
init(alert: UIAlertController) {
self.alert = alert
}
/** When using observable(), the action is not needed. */
func button(_ title: String, style: UIAlertActionStyle = .default, action: AlertAction? = nil) -> AlertBuilder {
let buttonIndex = alert.actions.count …Run Code Online (Sandbox Code Playgroud)