redondo rectangular plisado para ovalada modelos manteles mantel las hacer eventos esquinas dobles cuadrado cuadradas coser corta como ios cocoa-touch xamarin.ios quartz-graphics

ios - rectangular - UIView con esquinas redondeadas: ¿cómo recortar subvistas correctamente?



como se corta un mantel para mesa ovalada (2)

Es posible (y, de hecho, muy fácil) especificar determinadas esquinas redondeadas sin recurrir a drawRect: o dibujar manualmente un rectángulo parcialmente redondeado en una capa. Ver mi respuesta en una pregunta similar.

UIView una subclase de UIView que reemplaza a drawRect: y usa AddArcToPoint() para dibujar esquinas redondeadas. (No quiero usar la propiedad de radio de esquina de la capa porque necesito definir qué esquinas deben redondearse). Sin embargo, no puedo superar el problema: si agrego una subvista en (0 | 0), oculta mi ronda esquinas ¿Alguna idea de cómo puedo arreglar esto? Me gustaría que se recorte muy bien.

Aquí está el código que dibuja el rectángulo redondeado de las esquinas. Es Monotouch pero debería ser legible por cualquier desarrollador.

(Puede encontrar el código completo aquí: https://github.com/Krumelur/RoundedRectView )

public override void Draw (RectangleF rect) { using (var oContext = UIGraphics.GetCurrentContext()) { oContext.SetLineWidth (this.StrokeWidth); oContext.SetStrokeColor (this.oStrokeColor.CGColor); oContext.SetFillColor (this.oRectColor.CGColor); RectangleF oRect = this.Bounds; float fRadius = this.CornerRadius; float fWidth = oRect.Width; float fHeight = oRect.Height; // Make sure corner radius isn''t larger than half the shorter side. if (fRadius > fWidth / 2.0f) { fRadius = fWidth / 2.0f; } if (fRadius > fHeight / 2.0f) { fRadius = fHeight / 2.0f; } float fMinX = oRect.GetMinX (); float fMidX = oRect.GetMidX (); float fMaxX = oRect.GetMaxX (); float fMinY = oRect.GetMinY (); float fMidY = oRect.GetMidY (); float fMaxY = oRect.GetMaxY (); // Move to left middle. oContext.MoveTo (fMinX, fMidY); // Arc to top middle. oContext.AddArcToPoint (fMinX, fMinY, fMidX, fMinY, (this.RoundCorners & ROUND_CORNERS.TopLeft) == ROUND_CORNERS.TopLeft ? fRadius : 0); // Arc to right middle. oContext.AddArcToPoint (fMaxX, fMinY, fMaxX, fMidY, (this.RoundCorners & ROUND_CORNERS.TopRight) == ROUND_CORNERS.TopRight ? fRadius : 0); // Arc to bottom middle. oContext.AddArcToPoint (fMaxX, fMaxY, fMidX, fMaxY, (this.RoundCorners & ROUND_CORNERS.BottomRight) == ROUND_CORNERS.BottomRight ? fRadius : 0); // Arc to left middle. oContext.AddArcToPoint (fMinX, fMaxY, fMinX, fMidY, (this.RoundCorners & ROUND_CORNERS.BottomLeft) == ROUND_CORNERS.BottomLeft ? fRadius : 0); // Draw the path. oContext.ClosePath (); oContext.DrawPath (CGPathDrawingMode.FillStroke); } }

EDITAR:

Aquí hay un fragmento de código que muestra cómo resolverlo usando CALayer.

private void UpdateMask() { UIBezierPath oMaskPath = UIBezierPath.FromRoundedRect (this.Bounds, this.eRoundedCorners, new SizeF (this.fCornerRadius, this.fCornerRadius)); CAShapeLayer oMaskLayer = new CAShapeLayer (); oMaskLayer.Frame = this.Bounds; oMaskLayer.Path = oMaskPath.CGPath; this.Layer.Mask = oMaskLayer; }


No lo he probado, pero creo que podrías usar la propiedad de la máscara de CALayer para hacer esto. Tendría que dibujar su rectángulo redondeado en una capa que se configuró como la máscara a su capa de vista.