小编Stu*_*art的帖子

如何"取消"自定义容器控制器转换的视图外观转换

我创建了一个自定义容器控制器,其工作方式类似于UIPageViewController我可以实现一些自定义转换和数据源逻辑.我试图模仿新的客户视图控制器转换API在iOS 7中的工作方式,除了在取消转换时视图外观回调的一些恼人的怪癖之外它运行良好...

也就是说,执行过渡时,当正好应beginAppearanceTransition:animated:endAppearanceTransition被调用?


我的自定义容器类有一些代码如下:

- (BOOL)shouldAutomaticallyForwardAppearanceMethods
{
    return NO;  // Since the automatic callbacks are wrong for our custom transition.
}

- (void)startTransition:(CustomTransitionContext *)context
{
    // Get reference to the view controllers involved in the transition.
    UIViewController *oldVC = [context viewControllerForKey:UITransitionContextFromViewController];
    UIViewController *newVC = [context UITransitionContextToViewController];

    // Prepare parent/child relationship changes.
    [oldVC willMoveToParentViewController:nil];
    [self addChildViewController:newVC];

    // Begin view appearance transitions.
    [oldVC beginAppearanceTransition:NO animated:[context isAnimated]];
    [newVC beginAppearanceTransition:YES animated:[context isAnimated]];

    // Register a completion …
Run Code Online (Sandbox Code Playgroud)

transitions uiviewcontroller ios ios7 custom-transition

16
推荐指数
1
解决办法
4420
查看次数

未实现的委托方法导致崩溃

我创建了一个协议并将其分配给委托对象

@protocol AppBrainDelegate <NSObject>
@optional
- (void)didLocateUser;
- (void)didFinishLoadingDataWithData:(NSDictionary *)fetchedData;
@end

@interface Brain : NSObject
@property (strong, nonatomic) id <AppBrainDelegate> delegate;
Run Code Online (Sandbox Code Playgroud)

我认为协议声明中@optional的含义意味着,如果控制器不想要,则控制器不必监听委托方法.

如果没有在控制器中实现第一个委托方法,那么这是崩溃日志.如果我这样做,我不会崩溃.好像我不明白将委托方法声明为可选的概念.你能解释一下我的错误在哪里吗?

*由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:' - [EventViewController didLocateUser]:无法识别的选择器发送到实例0x1fb300'

delegates objective-c ios

12
推荐指数
1
解决办法
6317
查看次数

如何使用UICollectionViewTransitionLayout插入自定义UICollectionViewLayoutAttributes属性

我有两个UICollectionViewLayout使用自定义UICollectionViewLayoutAttributes子类的自定义对象.这些自定义属性添加一个属性tintAlpha,该属性控制附加到每个集合视图单元格的色调覆盖视图的不透明度.

我现在想要使用UICollectionViewTransitionLayout子类在这两个布局之间进行转换.如何配置转换布局子类以tintAlpha在我的自定义布局属性上插入自定义属性?

我可以这样做:

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
     CustomLayoutAttributes *attr = [super layoutAttributesForItemAtIndexPath:indexPath];

     CustomLayoutAttributes *fromAttr = (CustomLayoutAttributes *)[self.currentLayout layoutAttributesForItemAtIndexPath:indexPath];
     CustomLayoutAttributes *toAttr = (CustomLayoutAttributes *)[self.nextLayout layoutAttributesForItemAtIndexPath:indexPath];

     CGFloat t = self.transitionProgress;
     attr.tintAlpha = (1.0f - t) * fromAttr.tintAlpha + t * toAttr.tintAlpha;

     return attr;
}
Run Code Online (Sandbox Code Playgroud)

但是,这将忽略应用于当前或下一个布局中的initialLayoutAttributesForAppearingItemAtIndexPath:&属性的任何更改finalLayoutAttributesForDisappearingItemAtIndexPath:,因此实际上并不正确.据我所知,默认实现UICollectionViewTransitionLayout确定适当的from/to属性并缓存它们,或者在prepareLayout或中layoutAttributesForItemAtIndexPath:.拥有一些公共API UICollectionViewTransitionLayout以允许我们从属性对象访问这些对象是非常有用的,就好像我尝试实现我自己的逻辑关于是否使用初始/最终属性与标准属性一样必须是默认实现中的一些差异.

在布局转换期间是否有更好的方法来插入这些自定义属性?


更新:

我刚刚遇到这个场景的另一个问题.在上面的代码中,取得当fromAttrtoAttr从当前/下一个布局直接地说,collectionViewnil用于当前布局(超过过渡至少第一次运行循环).如果布局完全取决于集合视图的边界 - 例如考虑一个简单的封面流布局 - …

transitions ios uicollectionviewlayout

11
推荐指数
1
解决办法
2930
查看次数

为未命名的默认参数传递通用结构会导致垃圾属性

我在前一段时间创建的类中看到了一些奇怪的行为,似乎结构的属性在传递(复制)到方法后立即发生了变化.

我把它归结为一个可以在游乐场中运行的简单测试用例:

struct StructToPass<T> {
    let x: T
}

class MyClass<T> {
    func createAndPassStructWithValue(value: T) {
        let structToPass = StructToPass(x: value)
        println("Before passing to method: \(structToPass.x)")
        passStruct(structToPass)
    }

    func passStruct(_ theStruct: StructToPass<T>? = nil) {
        println("Inside method: \(theStruct!.x)")
    }
}

let myClass = MyClass<Int>()
myClass.createAndPassStructWithValue(42)
Run Code Online (Sandbox Code Playgroud)

查看相关的打印语句,它表明struct的x属性已更改:

// Before passing to method: 42
// Inside method: 140734543799888
Run Code Online (Sandbox Code Playgroud)


在类外创建结构并passStruct(_:)直接调用会导致操场崩溃,就像写passStruct(_:)一个函数一样:

// Causes playground to crash:
let aStruct = StructToPass(x: 42)
myClass.passStruct(aStruct)

// Also causes playground to crash: …
Run Code Online (Sandbox Code Playgroud)

generics parameters struct default-parameters swift

11
推荐指数
1
解决办法
269
查看次数

动画CALayer的shadowPath属性

我知道CALayer的shadowPath只能使用显式动画制作动画,但是我仍然无法使其工作.我怀疑我没有toValue正确传递- 我知道这必须是一个id,但该属性需要一个CGPathRef.将其存储在一个UIBezierPath似乎不起作用.我使用以下代码进行测试:

CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:@"shadowPath"];
theAnimation.duration = 3.0;
theAnimation.toValue = [UIBezierPath bezierPathWithRect:CGRectMake(-10.0, -10.0, 50.0, 50.0)];
[self.view.layer addAnimation:theAnimation forKey:@"animateShadowPath"];
Run Code Online (Sandbox Code Playgroud)

(我使用负值,以确保阴影延伸到位于其顶部的视图之外...图层的masksToBounds属性设置为NO).

shadowPath的动画是如何实现的?

UPDATE

问题差点解决了.不幸的是,主要问题是有点粗心的错误......

我犯的错误是将动画添加到视图控制器的根层,而不是我专用于阴影的图层.另外,@ pe8ter是正确的,因为toValue需要成为一个CGPathRef演员id(显然当我在尝试这个之前因为错误的图层错误而仍然没有动画).动画使用以下代码:

CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:@"shadowPath"];
theAnimation.duration = 3.0;
theAnimation.toValue = (id)[UIBezierPath bezierPathWithRect:myRect].CGPath;
[controller.shadowLayer addAnimation:theAnimation forKey:@"shadowPath"];
Run Code Online (Sandbox Code Playgroud)

我很欣赏这很难从我提供的示例代码中找到.希望它仍然可以用于处于类似情况的人.

但是,当我尝试添加该行时

controller.shadowLayer.shadowPath = [UIBezierPath bezierPathWithRect:myRect].CGPath;
Run Code Online (Sandbox Code Playgroud)

动画停止工作,阴影立即跳到最终位置.文档说添加动画时使用与要更改的属性相同的键,以覆盖设置属性值时创建的隐式动画,但是shadowPath无法生成隐式动画...所以如何获取新属性留的动画?

animation shadow calayer ios

9
推荐指数
1
解决办法
1万
查看次数

Xcode 4.1行为 - 自动关闭标签?

我已经设置了我的行为,以便在成功运行构建时,Xcode将打开一个自定义调试窗口.我希望在运行完成时关闭此窗口,但是我看不到这个选项.我能管理的最好的方法是将焦点返回到我的主窗口而不关闭调试窗口.

我有两个显示器设置,大部分时间使用第二个显示器为Xcode组织器.显然,在运行应用程序时,调试窗口对我来说更有用,但是我想让我的组织者重新回到顶层.

Xcode 4.1中是否存在"关闭标签"行为或类似行为?

谢谢

更新:

只是说我已向Apple提交了功能请求.由于大多数其他行为都有显示/隐藏的选项(一个弹出菜单),因此看起来这也应该是标签/窗口的一个选项.

xcode tabs behavior xcode4 xcode4.1

9
推荐指数
1
解决办法
893
查看次数

在if语句中计算可选对象的Bool属性

我正在寻找一种Bool在单个if语句中简洁地评估Swift的方法,当它Bool是可选对象的属性时:

var objectWithBool: ClassWithBool?
// ...

if let obj = objectWithBool {
    if obj.bool {
        // bool == true
    } else {
        // bool == false
    }
} else {
    // objectWithBool == nil
}
Run Code Online (Sandbox Code Playgroud)

是否有办法结合这些if陈述?在Objective-C中,这可以很容易地完成,因为nil可以在同一个表达式中评估对象:

if (objectWithBool.bool) {
    // bool == true
} else {
    // bool == false || objectWithBool == nil
}
Run Code Online (Sandbox Code Playgroud)

evaluation boolean optional swift

9
推荐指数
1
解决办法
3862
查看次数

向每个单元格添加带有cornerRadius的UILabel时,UITableView会爬行

我正在为表视图中的每个单元格添加一个UILabel.这最初没有问题.当我使用layer.cornerRadius滚动来围绕UILabel的角落时,表格视图停止.

 UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(cell.bounds.origin.x+10 ,5, 30, 30)];
 label1.backgroundColor = ([[managedObject valueForKey:@"color"] hasPrefix:@"FFFFFF"]) ? [UIColor blackColor] : color;
 label1.layer.cornerRadius = 10.0f;
 [cell addSubview:label1];
Run Code Online (Sandbox Code Playgroud)

cornerradius uitableview uilabel ios

8
推荐指数
2
解决办法
4781
查看次数

用GLKit绘图

我正在尝试使用opengl编写游戏,但是我在使用新的glkit类和iOS的默认模板时遇到了很多麻烦.

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    if (!self.context) {
        NSLog(@"Failed to create ES context");
    }

    if(!renderer)
        renderer = [RenderManager sharedManager];
    tiles = [[TileSet alloc]init];

    GLKView *view = (GLKView *)self.view;
    view.context = self.context;
    view.drawableDepthFormat = GLKViewDrawableDepthFormat24;

    [self setupGL];
}

- (void)setupGL
{
    int width = [[self view] bounds].size.width;
    int height = [[self view] bounds].size.height;

    [EAGLContext setCurrentContext:self.context];

    self.effect = [[GLKBaseEffect alloc] init];
    self.effect.light0.enabled = GL_TRUE;
    self.effect.light0.diffuseColor = GLKVector4Make(0.4f, 0.4f, 0.4f, 1.0f);

    //Configure Buffers
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); …
Run Code Online (Sandbox Code Playgroud)

opengl-es ios ios5 glkit

8
推荐指数
2
解决办法
1万
查看次数

UIDocument和NSFileWrapper - 尽管有增量更改,但大文件需要很长时间才能保存

我有一个UIDocument基于应用程序,使用NSFileWrappers来存储数据.'master'文件包装器包含许多其他目录文件包装器,每个包装器代表文档的不同页面.

保存仅修改了一页的一小部分的大型文档UIDocument时,在后台花费很长时间写入更改(in writeContents:andAttributes:safelyToURL:forSaveOperation:error:).当然它应该只写出这个文件包装器的一个小改动......什么花了这么长时间?

我的contentsForType:error:覆盖返回一个新的目录文件包装器,其中包含主文件包装器的内容(例如,WWDC 2012会话218 - 使用带有UIDocument的iCloud):

- (id)contentsForType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
    if (!_fileWrapper) {
        [self setupEmptyDocument];
    }
    return [[NSFileWrapper alloc] initDirectoryWithFileWrappers:[_fileWrapper fileWrappers]];
}
Run Code Online (Sandbox Code Playgroud)

这里是Time Profiler的堆栈跟踪的可爱图片:

UIDocument写入堆栈跟踪速度慢

顺便提一下,它表示要保存的工作线程约为1.6s - 在实际运行时间内,这相当于大约8秒.


编辑:

有什么方法可以检查文件包装器是否需要写入磁盘?正因为如此,我可以确认我做某些奇怪的事情,比如当我做一个小改动时更新每个子文件包装器(尽管我确定我不是......).


编辑:

我进一步使用了CloudNotes示例应用程序,看起来NSFileWrapper 确实实现了增量保存,至少在这种情况下!我通过初始化一个包含100个音符的文档来测试它,每个音符包含大约5MB的数据.我在这里和那里做了一个小编辑(文本视图的单个字符更改将文档标记为需要保存),并大致记录每次保存所花费的时间.测试相对粗糙(并在模拟器上运行),但结果是这样的:

  • 第一次写:~8000ms
  • 第二次写:~4000ms
  • 第3次写:~300ms
  • 所有后续写入:~40ms

显然有很多因素会影响它所花费的时间,特别是因为它在后台线程中使用文件协调来节省,但总的来说趋势似乎总是这种指数衰减,直到所有写入变得非常快.

但我仍然想弄清楚为什么这不会发生在我的应用程序中.对于大型多页文档(大型,但仍然比我上面执行的CloudNotes测试的文档小很多倍),用户可以等待很多秒才能关闭文档.我不想把旋转器放在一个应该是瞬间的东西上.

save nsfilewrapper ios uidocument

8
推荐指数
1
解决办法
2837
查看次数