nui icon indicating copy to clipboard operation
nui copied to clipboard

UITextField different textRect for editing and static text. #344

Open sdkdimon opened this issue 8 years ago • 7 comments

UITextField+NUI.m fix override_editingRectForBounds method.

sdkdimon avatar Mar 26 '16 23:03 sdkdimon

The code you submitted causes an infinite recursion loop. Please test your additions before submitting them as a pull request. Additionally, I am hesitant to accept code that doesn't have some basic tests written as well.

Stunner avatar Mar 26 '16 23:03 Stunner

Yes i am test it with my project, works as i expect. About infinite recursion loop, please take a look on override_didMoveToWindow method, which occurs in UI categories, it also should cause an infinite recursion loop, but it doesn't, seems to be it is runtime magic (method swizzling).

``` javascript`

  • (void)override_didMoveToWindow { if (!self.isNUIApplied) { [self applyNUI]; } [self override_didMoveToWindow]; }

And what do you mean by tests, test project with this case ?

sdkdimon avatar Mar 27 '16 10:03 sdkdimon

NUISwizzler class implements swizzle for editingRectForBounds of UITextField and other methods for all views.

- (void)swizzleAll
{
   ............................
   [self swizzle:[UITextField class] methodName:@"editingRectForBounds:"];
   ............................
}
- (void)swizzle:(Class)class methodName:(NSString*)methodName
{
    SEL originalMethod = NSSelectorFromString(methodName);
    SEL newMethod = NSSelectorFromString([NSString stringWithFormat:@"%@%@", @"override_", methodName]);
    [self swizzle:class from:originalMethod to:newMethod];
}

- (void)swizzle:(Class)class from:(SEL)original to:(SEL)new
{
    Method originalMethod = class_getInstanceMethod(class, original);
    Method newMethod = class_getInstanceMethod(class, new);
    if (class_addMethod(class, original, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) {
        class_replaceMethod(class, new, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, newMethod);
    }
}

sdkdimon avatar Mar 27 '16 10:03 sdkdimon

If override_editingRectForBounds only calls the original method, should be editingRectForBounds simply excluded from swizzle?

alexeyt820 avatar Mar 27 '16 15:03 alexeyt820

I think, reason that override_editingRectForBounds exist, is for future features. At current version i never met of usage it.

sdkdimon avatar Mar 27 '16 16:03 sdkdimon

Cool if it works. But in order for me to be able to accept this PR, I need it to some with some rudimentary tests to ensure that this feature doesn't break in the future. Please add in tests and I'll be happy to revisit this.

Stunner avatar Apr 23 '16 09:04 Stunner

Sorry, but i am can't write test for this case, this is because that

- (CGRect)editingRectForBounds:(CGRect)bounds;

method is not called by XCTest.framework. I think by this reason NUI project does not have test case for "padding" property of UITextField, which swizzle textRectForBounds method.

// Padding apparently can't be modified during didMoveToWindow
- (CGRect)override_textRectForBounds:(CGRect)bounds {
    if ([self nuiShouldBeApplied] &&
        [NUISettings hasProperty:@"padding" withClass:self.nuiClass]) {
        UIEdgeInsets insets = [NUISettings getEdgeInsets:@"padding" withClass:self.nuiClass];
        return CGRectMake(bounds.origin.x + insets.left,
                          bounds.origin.y + insets.top,
                          bounds.size.width - (insets.left + insets.right),
                          bounds.size.height - (insets.top + insets.bottom));
    } else {
        return [self override_textRectForBounds:bounds];
    }
}

Just run NUIDemo project with my pull request, and you see that it runs correctly. Or tell me how I can write test for this case.

sdkdimon avatar Apr 25 '16 17:04 sdkdimon