【问题标题】:How to access view's subviews without crash while hooking Swift? (Jailbreak)如何在挂钩 Swift 时访问视图的子视图而不会崩溃? (越狱)
【发布时间】:2018-06-16 14:29:30
【问题描述】:

我有一个奇怪的问题,当我更改视图的背景时,我无法再看到作为该视图子视图的 UILabel。我无法转储计算器应用程序的标题,因为它在 Swift 中,而且我不知道 UILabel 的名称是什么,而 FLEXing 对此没有帮助。我想将子视图放在背景视图的前面(有两个子视图),但是我当前的两种方法都会使目标应用程序崩溃。不过,我试图看看我是否可以让它在最前面的一个上工作。

我的代码:

NSMutableArray *labels = [NSMutableArray arrayWithArray:((DisplayView*)self).allSubviews];
if ([labels count] > 0) {

    UILabel *mainLabel = labels[0];
    [self bringSubviewToFront:mainLabel];
    }

((DisplayView*)self).allSubviews = labels;

我也试过了:

    for (UILabel *label in ((DisplayView*)self).allSubviews) {
        if ([label isKindOfClass:[UILabel class]]) {
        [self bringSubviewToFront:label];
}

我需要一种替代方法来执行此操作,一种将所有子视图向前推进的方法,或者有人告诉我我做错了什么。 编辑,这是我的完整代码:

    @interface DisplayView
@property (nonatomic, copy, readwrite) UIColor *backgroundColor;
@property (nonatomic, assign, readwrite, getter=isHidden) BOOL hidden;
@property (nonatomic, assign, readwrite, getter=isOpaque) BOOL opaque;
@property (nonatomic, assign, readwrite) CGFloat alpha;
@property (nonatomic, copy, readwrite) NSArray *allSubviews;
@property (nonatomic, assign, readwrite) CALayer *layer;
@end

%hook DisplayView
-(void)layoutSubviews {
    ((DisplayView*)self).opaque = NO;
    ((DisplayView*)self).backgroundColor = [UIColor blackColor];
     ((DisplayView*)self).hidden = NO;
((DisplayView*)self).alpha = 1.0;

NSMutableArray *labels = [NSMutableArray arrayWithArray:((DisplayView*)self).layer.sublayers];
if ([labels count] > 0) {

    UILabel *mainLabel = labels[0];
    [self bringSubviewToFront:mainLabel];
}



}



%end

%ctor {
    %init(DisplayView=objc_getClass("Calculator.DisplayView"));
}

【问题讨论】:

  • 如果不把标签放在前面,你可以不把背景放在后面。
  • 我所做的只是改变背景颜色。另外,我自己找不到背景视图
  • 我明白了。改变背景颜色不应该影响视图在层次结构中的位置。如果找不到背景视图,您是如何更改背景颜色的。你能用那个代码更新一下吗?
  • 当我使用'self'时出现错误,在'id'类型的对象上找不到它,所以我必须这样做:((DisplayView*)self).opaque = NO ; ((DisplayView*)self).backgroundColor = [UIColor blackColor]; ((DisplayView*)self).hidden = NO; ((DisplayView*)self).alpha = 1.0;
  • 如果您可以显示您正在执行该操作的代码(如果可能,请使用完整方法),那么它会有所帮助。因此,按照您强制案例的方式,该类是一个 DisplayView。你不能只做[((DisplayView*)self).superview sendSubviewToBack:(DisplayView*)self]; 之类的事情吗(我认为这是正确的语法)。虽然如果你只是改变你展示的东西,它甚至不应该是需要的。

标签: objective-c jailbreak


【解决方案1】:

似乎有几个可能的问题。首先,UIView上没有allSubviews,应该是subviews

NSMutableArray *labels = [NSMutableArray arrayWithArray:((DisplayView*)self).subviews];
if ([labels count] > 0) {
  UILabel *mainLabel = labels[0];

(只是想指出你似乎没有改变数组,所以为什么要复制它?你可以直接访问self.subviews

其次,在CALayer 版本中,您将CALayer 转换为UIView

NSMutableArray *labels = [NSMutableArray arrayWithArray:((DisplayView*)self).layer.sublayers];
CALayer *mainLabel = labels.firstObject;
if (mainLabel) {
  [labels removeObjectAtIndex:0];
  [labels addObject:mainLabel];
  self.layer.sublayers = labels;
}

也许有些帮助

【讨论】:

  • 由于某种原因,两者都不起作用。标签仍未显示
猜你喜欢
  • 2019-08-28
  • 2017-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-24
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多