2012-12-06 27 views
7

मैं अपने कस्टम व्यू में drawRect: विधि UIView को ओवरराइड करने का प्रयास कर रहा हूं। हालांकि, मेरे विचार एक बॉर्डर की त्रिज्या के रूप में परिभाषित किया गया है:UIView ओवरराइडिंग drawRect कारण मास्क का पालन न करने का कारण बनता है ToBounds

sub = [[[NSBundle mainBundle] loadNibNamed:@"ProfileView" owner:self options:nil] objectAtIndex:0]; 
    [self addSubview:sub]; 
    [sub setUserInteractionEnabled:YES]; 
    [self setUserInteractionEnabled:YES]; 
    CALayer *layer = sub.layer; 
    layer.masksToBounds = YES; 
    layer.borderWidth = 5.0; 
    layer.borderColor = [UIColor whiteColor].CGColor; 
    layer.cornerRadius = 30.0; 

यह पूरी तरह से काम करता है और मेरे विचार के चारों ओर एक बॉर्डर की त्रिज्या के साथ एक अच्छा सीमा देता है (पीछे विकर्ण/सीधे सफेद लाइनों कोई आपत्ति नहीं है, वे है कुछ भी नहीं इस दृश्य के साथ क्या करना):

correct one

हालांकि, जब मैं मेरे विचार में drawRect: विधि ओवरराइड करने के लिए प्रयास करते हैं, मैं एक काले रंग की पृष्ठभूमि सीमा को मास्किंग नहीं देख सकता। मैं कुछ भी (वर्तमान में) नहीं करते हैं, यहां मेरे कोड है:

incorrect one

मैं लेकिन ड्रॉ विधि कुछ भी नहीं बदला है:

-(void)drawRect:(CGRect)rect{ 
    [super drawRect:rect]; 
} 

और यहाँ नतीजा है। मेरा विचार कोने त्रिज्या मुखौटा का पालन करते हुए मैं ड्रॉ विधि को ओवरराइड कैसे कर सकता हूं? क्या यह आईओएस में एक बग है या क्या मुझे कुछ याद आ रहा है?

उत्तर

3

मुझे पूरा उत्तर नहीं पता है, लेकिन मुझे पता है कि drawLayer:inContext: का UIView का कार्यान्वयन इस पर निर्भर करता है कि आपने drawRect: लागू किया है या नहीं। शायद मास्किंग/सीमाओं के लिए क्लिपिंग उन चीजों में से एक है जो अलग-अलग होती है।

  • अपनी पृष्ठभूमि पारदर्शी बनाने:

    - (void)drawRect:(CGRect)rect { 
        [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:30.0] addClip]; 
        [image drawInRect:rect]; // or whatever 
    } 
    
  • :

    layer.backgroundColor = [UIColor clearColor].CGColor; 
    
  • अपने कस्टम drawRect: अंदर अपने आप क्लिप

    आप अपनी समस्या को कई तरीकों से हल करने की कोशिश कर सकते कोनों को स्पष्ट रूप से तैयार करें:

    CGContextBeginPath(c); 
    CGContextAddArc(c, r, r, r, M_PI, 3*M_PI_2, 0); 
    CGContextAddLineToPoint(c, 0, 0); 
    CGContextClosePath(c); 
    CGContextClip(c); 
    [[UIColor grayColor] setFill]; 
    UIRectFill(rect); 
    

मैं WWDC 2010 से इस महान प्रस्तुति से उन पिछले 2 सुझाव चुरा लिया: (this index page में सूचीबद्ध वीडियो - annoyingly, कोई सीधा लिंक) Advanced Performance Optimization on iPhone OS

1

शायद आप

[super drawRect:rect] 

अपने drawRect के अंदर नहीं बुलाना चाहिए। Apple says कि:

आप UIView सीधे उपवर्ग हैं, तो इस विधि सुपर कॉल करने के लिए की जरूरत नहीं है अपने क्रियान्वयन की। हालांकि, अगर आप अलग-अलग दृश्य वर्ग को उपclassing कर रहे हैं, तो आपको अपने कार्यान्वयन में किसी बिंदु पर सुपर कॉल करना चाहिए।

ऐसा लगता है कि सुपर विधि को कॉल करने से अजीब व्यवहार होता है।

2

यह एक पुराना सवाल है, लेकिन मैं हाल ही में Abusing UIView शीर्षक वाला एक उपयोगी ब्लॉग पोस्ट पढ़ रहा था। इसमें लेखक drawRect को ओवरराइड करने के लिए सलाह देते हैं ताकि ऐसा करने के अन्य तरीके होने पर सीमा जोड़ने जैसे चीजें हों। वह कहते हैं,

drawRect: ओवरराइडिंग प्रदर्शन प्रदर्शन का कारण बनता है। मैंने इसे का प्रोफाइल नहीं किया है, इसलिए मुझे नहीं पता कि यह सामान्य परिस्थितियों (शायद यह नहीं है) के तहत एक संकेतक प्रदर्शन है, लेकिन ज्यादातर मामलों में, drawRect: ओवरराइड सेटिंग गुणों को पूरा कर सकते हैं एक दृश्य की परत संपत्ति पर। आप एक दृश्य के चारों ओर एक रूपरेखा आकर्षित करने के लिए की जरूरत है, यहाँ आप इसे कैसे करना होगा है:

#import <QuartzCore/QuartzCore.h> 

- (id)initWithFrame:(CGRect)frame { 
    self = [super initWithFrame:frame]; 
    if (self) { 
     self.layer.borderWidth = 2.f; 
     self.layer.borderColor = [UIColor redColor].CGColor; 
    } 
    return self; 

मुझे पता है यह शायद के माध्यम से दिखा काले रंग की पृष्ठभूमि की समस्या का समाधान नहीं है। यह सोचने के लिए बस कुछ और है।

1

दृश्य पर

opaque = false // NO for ObjC 

स्थापना समस्या का हल।

+0

यह सही उत्तर है। – Randy