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.