طبقة ضرب اختبار تعود طبقة فقط عند لمس النصف السفلي من طبقة

StackOverflow https://stackoverflow.com/questions/401040

سؤال

ولدي الطبقة الفرعية على عرض المدعومة من طبقة. يتم تعيين محتويات الطبقة الفرعية لصورة المرجع وهو المستطيل 25x25.
I إجراء اختبار ضرب على طبقة السوبر عندما يتم استدعاء أساليب touchesBegan وtouchesMoved. طريقة ضرب اختبار لا، في الواقع، تعود الطبقة الفرعية إذا لمست ذلك، ولكن فقط إذا تم لمس النصف السفلي من الصورة. إذا لمست النصف العلوي من الصورة، فإنها ترجع superlayer بدلا من ذلك.

وأنا لا أعرف OS فون يعوض عن tendancy المستخدم يلمس أن يكون أقل مما هو مقصود. حتى لو كنت تغيير حجم الطبقة الفرعية إلى حجم أكبر، 50X50، فإنه يسلك نفس السلوك.

وأي أفكار؟

هل كانت مفيدة؟

المحلول 6

وبفضل كيفن ...

وانتهى بي الأمر مجرد الإعادة قانون بلدي مع UIViews. وكان الكثير من المتاعب مجرد محاولة لمعرفة لماذا UIView لم أكن أعرف ما كان يجري طبقة لمسها. وكان بلدي المنطق كله وراء فكرة أنني سوف يكون لها 100+ العناصر التي تظهر على الشاشة في وقت واحد، ويعتقد أن الطبقات يكون من الأسهل على معالج من UIViews. لدي حتى التطبيق وتشغيل الآن، و 100 وجهات النظر لا يعطيها أي السقطات.

واقتراحي للآخرين هو مجرد عصا مع ضرب اختبار UIViews عندما يكون ذلك ممكنا، فإنه يجعل رمز أبسط من ذلك بكثير

نصائح أخرى

وثائق hitTest تقول:

/* Returns the farthest descendant of the layer containing point 'p'.
 * Siblings are searched in top-to-bottom order. 'p' is in the
 * coordinate system of the receiver's superlayer. */

وهكذا ما عليك القيام به (شيء من هذا القبيل):

CGPoint thePoint = [touch locationInView:self];
thePoint = [self.layer convertPoint:thePoint toLayer:self.layer.superlayer];
CALayer *theLayer = [self.layer hitTest:thePoint];

و(تكرار الجواب من وظيفة أخرى من أجل اكتمال ')

ويبدو أن طبقة ليست مجرد يتلقون اللمسات على بكسل السفلية. وبدلا من ذلك يبدو أن "الفعلية" على طبقة الشاشة ومحتويات طبقة تم تعريفها من قبل CGRects مختلفة. يتم عرض الصورة في cordinates المتوقع، في حين يقابل طبقة يستجيب لمسات أسفل الصورة. بواسطة أدناه، أعني أصل الصورة في (200، 200) وأصل الطبقة التي تستجيب لمسات هو في (200، 220).

وفيما يلي وأنا على نشر بعض رمز اختبار اعتدت على إعادة إنشاء المشكلة. أول وجهة نظري فرعية ثم ضعي تحكم الرأي. أي الأسباب الكامنة وراء هذه المشكلة هو موضع تقدير كبير.

وجهة نظري فرعية:

#import "myView.h"
#import <QuartzCore/QuartzCore.h>


@implementation myView


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    CGPoint currentLocation = [[touches anyObject] locationInView:self];

    CALayer *currentLayer = [self.layer hitTest:currentLocation];

    CGPoint center = [currentLayer position];

    NSLog([currentLayer valueForKey:@"isRootLayer"]);

    if(![currentLayer valueForKey:@"isRootLayer"]) {

        if (center.x != 200) {

            [currentLayer setPosition:CGPointMake(200.0f, 200.0f)];     

        } else {
            [currentLayer setPosition:CGPointMake(100.0f, 100.0f)];     

        }
    }
}


- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        // Initialization code
    }
    return self;
}


- (void)drawRect:(CGRect)rect {
    // Drawing code
}


- (void)dealloc {
    [super dealloc];
}


@end

وجهة نظري وحدة التحكم:

#import "layerTestViewController.h"
#import <QuartzCore/QuartzCore.h>


#define ELEMENT_PERIOD_SIZE 50
#define ELEMENT_GROUP_SIZE 50

@implementation layerTestViewController





// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];

    CALayer  *myLayer = [CALayer layer];
    CGRect layerFrame =CGRectMake(0.0f, 0.0f, ELEMENT_GROUP_SIZE, ELEMENT_PERIOD_SIZE);
    myLayer.frame = layerFrame; 

    [myLayer setName:[NSString stringWithString:@"test"]];
    [myLayer setValue:[NSString stringWithString:@"testkey"] forKey:@"key"];

    UIGraphicsBeginImageContext(layerFrame.size);
    [[UIColor blueColor] set];
    UIRectFill(layerFrame);
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    myLayer.contents = (id)[theImage CGImage];
    myLayer.position = CGPointMake(100.0f, 100.0f);

    [self.view.layer addSublayer:myLayer];   

    [self.view.layer setValue:[NSString stringWithString:@"YES"] forKey:@"isRootLayer"];
    NSLog([self.view.layer valueForKey:@"isRootLayer"]);

}




- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}


- (void)dealloc {
    [super dealloc];
}

@end

والجواب المقبول لا يحل المشكلة، ولكن الإجابة من طرف مصوت مخفى لا.

ولدي النافذة، وحدة تحكم الرأي والرأي. يتلقى عرض اللمسات ويدعو hitTest: على طبقة. كان لي نفس المشكلة وتبين أن نقطة في القول هو الصحيح، ولكن في hitTest: ذ تنسيق من النقطة 20px قبالة، الذي صادف أن يكون ارتفاع شريط الحالة.

وعن طريق تعيين نقطة إلى نظام الإحداثيات من superlayer على النحو الذي اقترحه مصوت مخفى يتم إصلاح هذه المشكلة. و"الغامض" superlayer هي طبقة جذر superview. في حالتي، هو طبقة نافذة (الإطار (0، 0، 320، 480)).

إذا يتم الاعتراف اللمسات على الجزء السفلي فقط، احتمال واحد هو أن subview أخرى تغطي النصف العلوي من هذا subview. هل لديك subviews متعددة أو صورة واحدة فقط؟ في حال كان لديك subviews متعددة وأي منهم لون الخلفية كما clearColor، محاولة إعطاء لون الخلفية الصلبة لللاختبار. أن طرق عليك أن تعرف إذا تم الحصول على تغطيتها subview عن طريق subview آخر أم لا.

وعلى أمل أن يساعد.

ولقد مبسطة قانون بلدي للعثور على المشكلة. وليس لدي سوى طبقة فرعية واحدة على الشاشة ولا subviews. رمز المذكورة أعلاه هو ما أنا على التوالي في محاكاة. وبما أن هناك طبقات فقط 2 على الشاشة، طبقة بدعم من وجهة نظر المضيفة والطبقة الفرعية اضفت، يجب أن لا شيء يتعارض مع اختبار ضرب.

في حالة لم يكن واضحا، عندما لمست الجزء العلوي من الطبقة الفرعية، واختبار ضربة إرجاع طبقة الدعم بدلا من ذلك. أيضا إذا كنت على اتصال طبقة دعم عند نقطة أسفل طبقة فرعية، يتم إرجاع الطبقة الفرعية من قبل الاختبار ضرب.

ومن الصعب أن أشرح ولكن إذا قمت بتشغيل التعليمات البرمجية، يصبح واضحا.

والشكر

وعندما أحاول التعليمات البرمجية الخاصة بك، وأحصل على السلوك الصحيح تقريبا، باستثناء غالبا ما تكون غير معترف بها لمسات على حافة جدا من الطبقة الفرعية. أنا مشوشة قليلا على ما يجري. قد ترغب في محاولة القيام شيء من هذا القبيل عند تسجيل لمسة، ورمي طبقة صغيرة جديدة تصل التي وقع فيها اتصال (مثل مربع 5X5 بعض اللون) ومن ثم إزالته مرة أخرى 3 ثوان في وقت لاحق. وبهذه الطريقة يمكنك تتبع حيث يعتقد CA لمسة وقعت مقابل حيث المؤشر الخاص بك هو في الواقع.

وراجع للشغل، لا تحتاج إلى إنشاء CGImage للمحتوى الأزرق الخاص بك، يمكنك تعيين فقط backgroundColor طبقة ل[UIColor blueColor].CGColor.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top