mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
feat: add ability to pass touch event thru parent view (#135)
* [WIP] feat: enhance hit-testing support * refactor(ios): update passthroughParent logic as per reqs * refactor: move isPassthroughParentEnabled to LayoutBase * refactor: renames
This commit is contained in:
@@ -1,15 +0,0 @@
|
|||||||
package org.nativescript.widgets;
|
|
||||||
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by hhristov on 2/22/17.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public final class DisableUserInteractionListener extends Object implements View.OnTouchListener {
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,6 +6,7 @@ package org.nativescript.widgets;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
@@ -20,6 +21,11 @@ public abstract class LayoutBase extends ViewGroup {
|
|||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean passThroughParent;
|
||||||
|
|
||||||
|
public boolean getPassThroughParent() { return this.passThroughParent; }
|
||||||
|
public void setPassThroughParent(boolean value) { this.passThroughParent = value; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected LayoutParams generateDefaultLayoutParams() {
|
protected LayoutParams generateDefaultLayoutParams() {
|
||||||
return new CommonLayoutParams();
|
return new CommonLayoutParams();
|
||||||
@@ -59,6 +65,18 @@ public abstract class LayoutBase extends ViewGroup {
|
|||||||
public boolean shouldDelayChildPressedState() {
|
public boolean shouldDelayChildPressedState() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
if (!this.passThroughParent) {
|
||||||
|
return super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayoutBase.onTouchEvent(ev) execution means no interactive child view handled
|
||||||
|
// the event so we let the event pass through to parent view of the layout container
|
||||||
|
// because passThroughParent is set to true
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected static int getGravity(View view) {
|
protected static int getGravity(View view) {
|
||||||
int gravity = -1;
|
int gravity = -1;
|
||||||
|
|||||||
@@ -9,6 +9,12 @@
|
|||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
8B7321CF1D097ECD00884AC6 /* TNSLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7321CD1D097ECD00884AC6 /* TNSLabel.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
8B7321CF1D097ECD00884AC6 /* TNSLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7321CD1D097ECD00884AC6 /* TNSLabel.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
8B7321D01D097ECD00884AC6 /* TNSLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7321CE1D097ECD00884AC6 /* TNSLabel.m */; };
|
8B7321D01D097ECD00884AC6 /* TNSLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7321CE1D097ECD00884AC6 /* TNSLabel.m */; };
|
||||||
|
B8E76F52212C2DA2009CFCE2 /* NSObject+Swizzling.h in Headers */ = {isa = PBXBuildFile; fileRef = B8E76F50212C2DA2009CFCE2 /* NSObject+Swizzling.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||||
|
B8E76F53212C2DA2009CFCE2 /* NSObject+Swizzling.m in Sources */ = {isa = PBXBuildFile; fileRef = B8E76F51212C2DA2009CFCE2 /* NSObject+Swizzling.m */; };
|
||||||
|
B8E76F5A212C2F4E009CFCE2 /* NSObject+PropertyBag.h in Headers */ = {isa = PBXBuildFile; fileRef = B8E76F58212C2F4E009CFCE2 /* NSObject+PropertyBag.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||||
|
B8E76F5B212C2F4E009CFCE2 /* NSObject+PropertyBag.m in Sources */ = {isa = PBXBuildFile; fileRef = B8E76F59212C2F4E009CFCE2 /* NSObject+PropertyBag.m */; };
|
||||||
|
B8E76F5E212C3134009CFCE2 /* UIView+PassThroughParent.h in Headers */ = {isa = PBXBuildFile; fileRef = B8E76F5C212C3134009CFCE2 /* UIView+PassThroughParent.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
B8E76F5F212C3134009CFCE2 /* UIView+PassThroughParent.m in Sources */ = {isa = PBXBuildFile; fileRef = B8E76F5D212C3134009CFCE2 /* UIView+PassThroughParent.m */; };
|
||||||
F915D3551EC9EF5E00071914 /* TNSProcess.m in Sources */ = {isa = PBXBuildFile; fileRef = F915D3531EC9EF5E00071914 /* TNSProcess.m */; };
|
F915D3551EC9EF5E00071914 /* TNSProcess.m in Sources */ = {isa = PBXBuildFile; fileRef = F915D3531EC9EF5E00071914 /* TNSProcess.m */; };
|
||||||
F915D3561EC9EF5E00071914 /* TNSProcess.h in Headers */ = {isa = PBXBuildFile; fileRef = F915D3541EC9EF5E00071914 /* TNSProcess.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
F915D3561EC9EF5E00071914 /* TNSProcess.h in Headers */ = {isa = PBXBuildFile; fileRef = F915D3541EC9EF5E00071914 /* TNSProcess.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
F98F5CB31CD0EFEA00978308 /* TNSWidgets.h in Headers */ = {isa = PBXBuildFile; fileRef = F98F5CB21CD0EFEA00978308 /* TNSWidgets.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
F98F5CB31CD0EFEA00978308 /* TNSWidgets.h in Headers */ = {isa = PBXBuildFile; fileRef = F98F5CB21CD0EFEA00978308 /* TNSWidgets.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
@@ -31,6 +37,12 @@
|
|||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
8B7321CD1D097ECD00884AC6 /* TNSLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TNSLabel.h; sourceTree = "<group>"; };
|
8B7321CD1D097ECD00884AC6 /* TNSLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TNSLabel.h; sourceTree = "<group>"; };
|
||||||
8B7321CE1D097ECD00884AC6 /* TNSLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TNSLabel.m; sourceTree = "<group>"; };
|
8B7321CE1D097ECD00884AC6 /* TNSLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TNSLabel.m; sourceTree = "<group>"; };
|
||||||
|
B8E76F50212C2DA2009CFCE2 /* NSObject+Swizzling.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSObject+Swizzling.h"; sourceTree = "<group>"; };
|
||||||
|
B8E76F51212C2DA2009CFCE2 /* NSObject+Swizzling.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSObject+Swizzling.m"; sourceTree = "<group>"; };
|
||||||
|
B8E76F58212C2F4E009CFCE2 /* NSObject+PropertyBag.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSObject+PropertyBag.h"; sourceTree = "<group>"; };
|
||||||
|
B8E76F59212C2F4E009CFCE2 /* NSObject+PropertyBag.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSObject+PropertyBag.m"; sourceTree = "<group>"; };
|
||||||
|
B8E76F5C212C3134009CFCE2 /* UIView+PassThroughParent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIView+PassThroughParent.h"; sourceTree = "<group>"; };
|
||||||
|
B8E76F5D212C3134009CFCE2 /* UIView+PassThroughParent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIView+PassThroughParent.m"; sourceTree = "<group>"; };
|
||||||
F915D3531EC9EF5E00071914 /* TNSProcess.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TNSProcess.m; path = ../TNSProcess.m; sourceTree = "<group>"; };
|
F915D3531EC9EF5E00071914 /* TNSProcess.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TNSProcess.m; path = ../TNSProcess.m; sourceTree = "<group>"; };
|
||||||
F915D3541EC9EF5E00071914 /* TNSProcess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TNSProcess.h; path = ../TNSProcess.h; sourceTree = "<group>"; };
|
F915D3541EC9EF5E00071914 /* TNSProcess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TNSProcess.h; path = ../TNSProcess.h; sourceTree = "<group>"; };
|
||||||
F98F5CAF1CD0EFEA00978308 /* TNSWidgets.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TNSWidgets.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
F98F5CAF1CD0EFEA00978308 /* TNSWidgets.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TNSWidgets.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@@ -91,6 +103,12 @@
|
|||||||
F98F5CC91CD0F09E00978308 /* UIImage+TNSBlocks.h */,
|
F98F5CC91CD0F09E00978308 /* UIImage+TNSBlocks.h */,
|
||||||
F98F5CCA1CD0F09E00978308 /* UIImage+TNSBlocks.m */,
|
F98F5CCA1CD0F09E00978308 /* UIImage+TNSBlocks.m */,
|
||||||
F98F5CB41CD0EFEA00978308 /* Info.plist */,
|
F98F5CB41CD0EFEA00978308 /* Info.plist */,
|
||||||
|
B8E76F50212C2DA2009CFCE2 /* NSObject+Swizzling.h */,
|
||||||
|
B8E76F51212C2DA2009CFCE2 /* NSObject+Swizzling.m */,
|
||||||
|
B8E76F58212C2F4E009CFCE2 /* NSObject+PropertyBag.h */,
|
||||||
|
B8E76F59212C2F4E009CFCE2 /* NSObject+PropertyBag.m */,
|
||||||
|
B8E76F5C212C3134009CFCE2 /* UIView+PassThroughParent.h */,
|
||||||
|
B8E76F5D212C3134009CFCE2 /* UIView+PassThroughParent.m */,
|
||||||
);
|
);
|
||||||
path = TNSWidgets;
|
path = TNSWidgets;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -113,7 +131,10 @@
|
|||||||
files = (
|
files = (
|
||||||
F915D3561EC9EF5E00071914 /* TNSProcess.h in Headers */,
|
F915D3561EC9EF5E00071914 /* TNSProcess.h in Headers */,
|
||||||
F98F5CB31CD0EFEA00978308 /* TNSWidgets.h in Headers */,
|
F98F5CB31CD0EFEA00978308 /* TNSWidgets.h in Headers */,
|
||||||
|
B8E76F5E212C3134009CFCE2 /* UIView+PassThroughParent.h in Headers */,
|
||||||
F98F5CCB1CD0F09E00978308 /* UIImage+TNSBlocks.h in Headers */,
|
F98F5CCB1CD0F09E00978308 /* UIImage+TNSBlocks.h in Headers */,
|
||||||
|
B8E76F52212C2DA2009CFCE2 /* NSObject+Swizzling.h in Headers */,
|
||||||
|
B8E76F5A212C2F4E009CFCE2 /* NSObject+PropertyBag.h in Headers */,
|
||||||
8B7321CF1D097ECD00884AC6 /* TNSLabel.h in Headers */,
|
8B7321CF1D097ECD00884AC6 /* TNSLabel.h in Headers */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@@ -217,6 +238,9 @@
|
|||||||
8B7321D01D097ECD00884AC6 /* TNSLabel.m in Sources */,
|
8B7321D01D097ECD00884AC6 /* TNSLabel.m in Sources */,
|
||||||
F915D3551EC9EF5E00071914 /* TNSProcess.m in Sources */,
|
F915D3551EC9EF5E00071914 /* TNSProcess.m in Sources */,
|
||||||
F98F5CCC1CD0F09E00978308 /* UIImage+TNSBlocks.m in Sources */,
|
F98F5CCC1CD0F09E00978308 /* UIImage+TNSBlocks.m in Sources */,
|
||||||
|
B8E76F53212C2DA2009CFCE2 /* NSObject+Swizzling.m in Sources */,
|
||||||
|
B8E76F5B212C2F4E009CFCE2 /* NSObject+PropertyBag.m in Sources */,
|
||||||
|
B8E76F5F212C3134009CFCE2 /* UIView+PassThroughParent.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
17
ios/TNSWidgets/TNSWidgets/NSObject+PropertyBag.h
Normal file
17
ios/TNSWidgets/TNSWidgets/NSObject+PropertyBag.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// NSObject+PropertyBag.h
|
||||||
|
// TNSWidgets
|
||||||
|
//
|
||||||
|
// Created by Manol Donev on 21.08.18.
|
||||||
|
// Copyright © 2018 Telerik A D. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
|
||||||
|
@interface NSObject (PropertyBag)
|
||||||
|
|
||||||
|
- (id) propertyValueForKey:(NSString*) key;
|
||||||
|
- (void) setPropertyValue:(id) value forKey:(NSString*) key;
|
||||||
|
|
||||||
|
@end
|
||||||
62
ios/TNSWidgets/TNSWidgets/NSObject+PropertyBag.m
Normal file
62
ios/TNSWidgets/TNSWidgets/NSObject+PropertyBag.m
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// NSObject+PropertyBag.m
|
||||||
|
// TNSWidgets
|
||||||
|
//
|
||||||
|
// Created by Manol Donev on 21.08.18.
|
||||||
|
// Copyright © 2018 Telerik A D. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "NSObject+PropertyBag.h"
|
||||||
|
#import "NSObject+Swizzling.h"
|
||||||
|
|
||||||
|
|
||||||
|
@implementation NSObject (PropertyBag)
|
||||||
|
|
||||||
|
+ (void) load{
|
||||||
|
[self loadPropertyBag];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void) loadPropertyBag{
|
||||||
|
@autoreleasepool {
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
const SEL deallocSelector = NSSelectorFromString(@"dealloc"); //ARC forbids use of 'dealloc' in a @selector
|
||||||
|
[self swizzleInstanceMethodWithOriginalSelector:deallocSelector fromClass:self.class withSwizzlingSelector:@selector(propertyBag_dealloc)];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__strong NSMutableDictionary *_propertyBagHolder; // Properties for every class will go in this property bag
|
||||||
|
- (id) propertyValueForKey:(NSString*) key {
|
||||||
|
return [[self propertyBag] valueForKey:key];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setPropertyValue:(id) value forKey:(NSString*) key {
|
||||||
|
[[self propertyBag] setValue:value forKey:key];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMutableDictionary*) propertyBag {
|
||||||
|
if (_propertyBagHolder == nil) _propertyBagHolder = [[NSMutableDictionary alloc] initWithCapacity:100];
|
||||||
|
NSMutableDictionary *propBag = [_propertyBagHolder valueForKey:[[NSString alloc] initWithFormat:@"%p", self]];
|
||||||
|
if (propBag == nil) {
|
||||||
|
propBag = [NSMutableDictionary dictionary];
|
||||||
|
[self setPropertyBag:propBag];
|
||||||
|
}
|
||||||
|
|
||||||
|
return propBag;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setPropertyBag:(NSDictionary*) propertyBag {
|
||||||
|
if (_propertyBagHolder == nil) {
|
||||||
|
_propertyBagHolder = [[NSMutableDictionary alloc] initWithCapacity:100];
|
||||||
|
}
|
||||||
|
|
||||||
|
[_propertyBagHolder setValue:propertyBag forKey:[[NSString alloc] initWithFormat:@"%p", self]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)propertyBag_dealloc {
|
||||||
|
[self setPropertyBag:nil];
|
||||||
|
[self propertyBag_dealloc]; // swizzled
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
17
ios/TNSWidgets/TNSWidgets/NSObject+Swizzling.h
Normal file
17
ios/TNSWidgets/TNSWidgets/NSObject+Swizzling.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// NSObject+Swizzling.h
|
||||||
|
// TNSWidgets
|
||||||
|
//
|
||||||
|
// Created by Manol Donev on 21.08.18.
|
||||||
|
// Copyright © 2018 Telerik A D. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <objc/runtime.h>
|
||||||
|
|
||||||
|
|
||||||
|
@interface NSObject (Swizzling)
|
||||||
|
|
||||||
|
+ (void)swizzleInstanceMethodWithOriginalSelector:(SEL)originalSelector fromClass:(Class)classContainigOriginalSel withSwizzlingSelector:(SEL)swizzlingSelector;
|
||||||
|
|
||||||
|
@end
|
||||||
68
ios/TNSWidgets/TNSWidgets/NSObject+Swizzling.m
Normal file
68
ios/TNSWidgets/TNSWidgets/NSObject+Swizzling.m
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
//
|
||||||
|
// NSObject+Swizzling.m
|
||||||
|
// TNSWidgets
|
||||||
|
//
|
||||||
|
// Created by Manol Donev on 21.08.18.
|
||||||
|
// Copyright © 2018 Telerik A D. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "NSObject+Swizzling.h"
|
||||||
|
|
||||||
|
@implementation NSObject (Swizzling)
|
||||||
|
|
||||||
|
#pragma mark - Method Swizzling
|
||||||
|
|
||||||
|
+ (void)swizzleInstanceMethodWithOriginalSelector:(SEL)originalSelector
|
||||||
|
fromClass:(Class)classContainigOriginalSel
|
||||||
|
withSwizzlingSelector:(SEL)swizzlingSelector {
|
||||||
|
Method originalMethod = class_getInstanceMethod(classContainigOriginalSel, originalSelector);
|
||||||
|
Method swizzlingMethod = class_getInstanceMethod(self.class, swizzlingSelector);
|
||||||
|
[self swizzleMethodWithOriginalSelector:originalSelector
|
||||||
|
originalMethod:originalMethod
|
||||||
|
fromClass:classContainigOriginalSel
|
||||||
|
withSwizzlingSelector:swizzlingSelector
|
||||||
|
swizzlingMethod:swizzlingMethod];
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: Utilities
|
||||||
|
|
||||||
|
+ (void)swizzleMethodWithOriginalSelector:(SEL)originalSelector
|
||||||
|
originalMethod:(Method)originalMethod
|
||||||
|
fromClass:(Class)classContainigOriginalSel
|
||||||
|
withSwizzlingSelector:(SEL)swizzlingSelector
|
||||||
|
swizzlingMethod:(Method)swizzlingMethod {
|
||||||
|
if (self == classContainigOriginalSel) {
|
||||||
|
BOOL didAddMethod = class_addMethod(classContainigOriginalSel,
|
||||||
|
originalSelector,
|
||||||
|
method_getImplementation(swizzlingMethod),
|
||||||
|
method_getTypeEncoding(swizzlingMethod));
|
||||||
|
|
||||||
|
if (didAddMethod) {
|
||||||
|
class_replaceMethod(self.class,
|
||||||
|
swizzlingSelector,
|
||||||
|
method_getImplementation(originalMethod),
|
||||||
|
method_getTypeEncoding(originalMethod));
|
||||||
|
} else {
|
||||||
|
method_exchangeImplementations(originalMethod, swizzlingMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
class_addMethod(classContainigOriginalSel,
|
||||||
|
swizzlingSelector,
|
||||||
|
method_getImplementation(originalMethod),
|
||||||
|
method_getTypeEncoding(originalMethod));
|
||||||
|
|
||||||
|
class_replaceMethod(classContainigOriginalSel,
|
||||||
|
originalSelector,
|
||||||
|
method_getImplementation(swizzlingMethod),
|
||||||
|
method_getTypeEncoding(swizzlingMethod));
|
||||||
|
|
||||||
|
class_replaceMethod(self,
|
||||||
|
swizzlingSelector,
|
||||||
|
method_getImplementation(originalMethod),
|
||||||
|
method_getTypeEncoding(originalMethod));
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -17,5 +17,6 @@ FOUNDATION_EXPORT const unsigned char TNSWidgetsVersionString[];
|
|||||||
// In this header, you should import all the public headers of your framework using statements like #import <TNSWidgets/PublicHeader.h>
|
// In this header, you should import all the public headers of your framework using statements like #import <TNSWidgets/PublicHeader.h>
|
||||||
|
|
||||||
#import "UIImage+TNSBlocks.h"
|
#import "UIImage+TNSBlocks.h"
|
||||||
|
#import "UIView+PassThroughParent.h"
|
||||||
#import "TNSLabel.h"
|
#import "TNSLabel.h"
|
||||||
#import "TNSProcess.h"
|
#import "TNSProcess.h"
|
||||||
|
|||||||
17
ios/TNSWidgets/TNSWidgets/UIView+PassthroughParent.h
Normal file
17
ios/TNSWidgets/TNSWidgets/UIView+PassthroughParent.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// UIView+PassThroughParent.h
|
||||||
|
// TNSWidgets
|
||||||
|
//
|
||||||
|
// Created by Manol Donev on 21.08.18.
|
||||||
|
// Copyright © 2018 Telerik A D. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
|
||||||
|
@interface UIView (PassThroughParent)
|
||||||
|
|
||||||
|
- (BOOL) passThroughParent;
|
||||||
|
- (void) setPassThroughParent:(BOOL) passThroughParent;
|
||||||
|
|
||||||
|
@end
|
||||||
53
ios/TNSWidgets/TNSWidgets/UIView+PassthroughParent.m
Normal file
53
ios/TNSWidgets/TNSWidgets/UIView+PassthroughParent.m
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// UIView+PassThroughParent.m
|
||||||
|
// TNSWidgets
|
||||||
|
//
|
||||||
|
// Created by Manol Donev on 21.08.18.
|
||||||
|
// Copyright © 2018 Telerik A D. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "UIView+PassThroughParent.h"
|
||||||
|
#import "NSObject+Swizzling.h"
|
||||||
|
#import "NSObject+PropertyBag.h"
|
||||||
|
|
||||||
|
|
||||||
|
NSString * const TLKPassThroughParentKey = @"passThroughParent";
|
||||||
|
|
||||||
|
@implementation UIView (PassThroughParent)
|
||||||
|
|
||||||
|
+ (void) load {
|
||||||
|
[self loadHitTest];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void) loadHitTest {
|
||||||
|
@autoreleasepool {
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
[self swizzleInstanceMethodWithOriginalSelector:@selector(hitTest:withEvent:) fromClass:self.class withSwizzlingSelector:@selector(passThrough_hitTest:withEvent:)];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)passThroughParent {
|
||||||
|
NSNumber *passthrough = [self propertyValueForKey:TLKPassThroughParentKey];
|
||||||
|
if (passthrough) {
|
||||||
|
return passthrough.boolValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setPassThroughParent:(BOOL)passThroughParent {
|
||||||
|
[self setPropertyValue:[NSNumber numberWithBool:passThroughParent] forKey:TLKPassThroughParentKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIView *)passThrough_hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
||||||
|
UIView *hitTestView = [self passThrough_hitTest:point withEvent:event]; // swizzled
|
||||||
|
if (hitTestView == self && self.passThroughParent) {
|
||||||
|
hitTestView = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hitTestView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
Reference in New Issue
Block a user