2012-11-30 54 views
2

我想要UITextView的子類能夠用自定義邊框加頂部+左側內部陰影來繪製圓形矩形。在UITextView上滾動內部陰影

我在創建此效果(通過閱讀this後)獲得任何(靜態邊界)視圖的巨大成功,但有滾動視圖的問題。

這個效果我做我的自定義類的-setFrame實例方法:

- (void)setFrame:(CGRect)frame { 
[super setFrame:frame]; 

UIColor *borderColor = [UIColor colorWithRed:BORDER_COLOR_RED green:BORDER_COLOR_GREEN blue:BORDER_COLOR_BLUE alpha:BORDER_COLOR_ALPHA]; 

// Store index of the shadow sublayer for future use 
[self setShadowLayerIndex:[LayerFormatter formatAsRoundRectWithShadowOn:self withBackgroundColor:[UIColor whiteColor] andBorderColor:borderColor]];} 

formatAsRoundRectWithShadowOn:是定義爲類方法:

+(NSUInteger)formatAsRoundRectWithShadowOn:(UIView*)view withBackgroundColor:(UIColor *)backgroundColor andBorderColor:(UIColor *)borderColor { 
if([view isKindOfClass:[UITextField class]]) 
    ((UITextField*)view).borderStyle = UITextBorderStyleNone; 
view.backgroundColor = backgroundColor; 

view.layer.borderWidth = 1.0; 
view.layer.borderColor = [borderColor CGColor]; 
view.layer.cornerRadius = CORNER_RADIUS; 
view.layer.masksToBounds = YES; 

//Add some insets to the text: https://stackoverflow.com/a/4423805 
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)]; 

if([view isKindOfClass:[UITextField class]]) 
{ 
    ((UITextField*)view).leftView = paddingView; 
    ((UITextField*)view).leftViewMode = UITextFieldViewModeAlways; 
} 

// Create and apply a shadow layer. Help here: https://stackoverflow.com/questions/4431292/inner-shadow-effect-on-uiview-layer 
CAShapeLayer* shadowLayer = [CAShapeLayer layer]; 

[shadowLayer setFrame:view.bounds]; 
[shadowLayer setShadowColor:[[UIColor blackColor] CGColor]]; 
[shadowLayer setShadowRadius:3.0f]; 
[shadowLayer setShadowOpacity:0.35f]; 
[shadowLayer setShadowOffset:CGSizeMake(2.0f, 2.0f)]; 

[shadowLayer setFillColor:[backgroundColor CGColor]]; 

// Causes the inner region in this example to NOT be filled. 
[shadowLayer setFillRule:kCAFillRuleEvenOdd]; 

// Create inner and outer rectangle paths. 
CGMutablePathRef path = CGPathCreateMutable(); 

// Outer path should be bigger than the field 
UIBezierPath *bpOuter = [UIBezierPath bezierPathWithRect:CGRectInset(shadowLayer.bounds, -10, -10)]; 

// Inner path is the visible part of the view 
UIBezierPath *bpInner = [UIBezierPath bezierPathWithRoundedRect:shadowLayer.bounds cornerRadius:CORNER_RADIUS]; 

// Add outer path and then add the inner path so it's subtracted from the outer path. 
CGPathAddPath(path, NULL, bpOuter.CGPath); 
CGPathAddPath(path, NULL, bpInner.CGPath); 

CGPathCloseSubpath(path); 

[shadowLayer setPath:path]; 
CGPathRelease(path); 

[[view layer] addSublayer:shadowLayer]; 

NSUInteger addedAtIndex = [[[view layer] sublayers] indexOfObject:shadowLayer]; 
return addedAtIndex;} 

要正確處理陰影+邊框顯示器當文字視圖滾動我使用我的自定義類-setBounds方法來更新陰影層框架:

-(void)setBounds:(CGRect)bounds{ 
[super setBounds:bounds]; 

// Change the frame of the shadow layer to reflect new bounds 
[[[[self layer] sublayers] objectAtIndex:self.shadowLayerIndex] setFrame:bounds];} 

我遇到的問題是在向下滾動時(插入新的文本行時)或頂部(滾動到文本的開頭處)時底部的陰影+框架繪製不正確。

插入新行或滾動完成後(視圖再次爲靜態),視圖繪製正確。

對這個問題的任何見解都非常值得歡迎。

回答

1

我有一段時間來深入研究這個問題,並找到了我想要分享的解決方案。

起初我意識到最好在-awakeFromNib而不是-setFrame中設置陰影層。

當文本視圖滾動時處理正確的陰影+邊框顯示我已經改變了這樣的方法:更新陰影層我現在使用-layoutSubviews覆蓋在我的自定義類中。 在-layoutSubviews覆蓋我重新創建陰影層尊重新的界限,然後調用[super layoutSubviews]

滾動,改變方向 - 它就像一個魅力!

- (void)layoutSubviews 
{ 
    [self updateShadow]; 
    [super layoutSubviews]; 
} 

- (void)updateShadow 
{ 
    if (shadowLayer) 
     [shadowLayer removeFromSuperlayer]; 

    shadowLayer = [LayerFormatter addInnerShadowLayerOn:self withShadowColor:[UIColor blackColor]]; 
} 

注意+(NSUInteger)formatAsRoundRectWithShadowOn:(UIView*)view withBackgroundColor:(UIColor *)backgroundColor andBorderColor:(UIColor *)borderColor現在返回層參考視圖的層層次中已經添加層(返工很簡單):

+(CAShapeLayer *)addInnerShadowLayerOn:(UIView *)view withShadowColor:(UIColor *)shadowColor; 

任何證據/意見,這種做法是正確的,而不是隻是工作將不勝感激。