Draw Rect Monotouch PaintCode - ios

I'm trying to make a better UI for my application but I'm stuck in this. My designing skills aren't good so I'm trying PaintCode.
I want to make a Login Screen with this shadow beneath the group of username and password.
I can't use a UIView so I made the same but in PaintCode using a Rect.
var context = UIGraphics.GetCurrentContext();
//// Shadow Declarations
var shadow = UIColor.DarkGray.ColorWithAlpha(0.71f).CGColor;
var shadowOffset = new SizeF(6.1f, 4.1f);
var shadowBlurRadius = 5.0f;
//// Rectangle Drawing
UIBezierPath rectanglePath = new UIBezierPath();
rectanglePath.MoveTo(new PointF(18.0f, 239.0f));
rectanglePath.AddLineTo(new PointF(383.0f, 239.0f));
rectanglePath.AddLineTo(new PointF(383.0f, 13.0f));
rectanglePath.AddLineTo(new PointF(18.0f, 13.0f));
rectanglePath.AddLineTo(new PointF(18.0f, 239.0f));
rectanglePath.ClosePath();
context.SaveState();
context.SetShadowWithColor(shadowOffset, shadowBlurRadius, shadow);
UIColor.White.SetFill();
rectanglePath.Fill();
context.RestoreState();
Now I don't know what to do with that code. In the tutorials and documentation they usually make a UIView so they just subclass a UIView and add it in Interface Builder, that way you can always know exactly where the object is going to end in your final app. I don't know what to subclass and how to make the rect I draw beneath my username and password boxes.

Create a custom class inheriting from UIView, then override Draw function and put your custom code there.
[Register("DrawView")]
public class DrawView : UIView
{
public override void Draw(System.Drawing.RectangleF rect)
{
In the above sample the Register attribute is necessary if you want to use your control from XCode designer (or Xamarin Storyboard designer).

Related

How to set Dashed border color in xamarin forms Frame in iOS?

I am doing an app in Xamarin.Forms for iOS.In that i need to do a design of the image shown below.
To achieve this design I used a frame and added border color for it.But I am not able to get Dashed border as specified in the image above. I am trying to get this through custom renderer. Can anyone please help me or guide me to get the exact design in the image.
That would be a gret help for me.Thanks in advance.
You can extend the Frame Renderer and add the dash pattern
public class CustomFrame : FrameRenderer
{
public override void LayoutSubviews()
{
base.LayoutSubviews();
CAShapeLayer viewBorder = new CAShapeLayer();
viewBorder.StrokeColor = UIColor.Red.CGColor;
viewBorder.FillColor = null;
viewBorder.LineDashPattern = new NSNumber[] { new NSNumber(5), new NSNumber(2) };
viewBorder.Frame = NativeView.Bounds;
viewBorder.Path = UIBezierPath.FromRect(NativeView.Bounds).CGPath;
Layer.AddSublayer(viewBorder);
// If you don't want the shadow effect
Element.HasShadow = false;
}
}

I can not get this UIView round

This is the final result of the code below:
This is my code:
view.layer.cornerRadius = 0.5 * view.bounds.size.width
view.layer.masksToBounds = true
view.clipsToBounds = true
view is the red UIView. This code is placed in viewWillLayoutSubviews and viewDidLayoutSubviews (not together, but I both tested them).
Besides this SO is not clear about using masksToBounds OR clipsToBounds. I am not sure what to use and when to use one of them above. I also tested it apart.
The green UIView has also clipsToBounds active and rounded corners, but if I remove them both, I still get the same effect... I hope someone can help. This only occurs when I place a UIView, inside another UIView. If the UIView does not has a parent, it works (I get the UIView rounded).
Edit: GitHub link: https://github.com/Jasperav/tests
The problem lies with when the auto-layout engine actually finishes all the layout calculations.
If you move your code to viewDidAppear you will see properly "rounded" corners.
This is a very common case for using a custom view though. In fact, it's easily used as an "IBDesignable" class, so you can see it rendered in Interface Builder.
Create a new file named "RoundedView.swift" with this code:
import UIKit
#IBDesignable
class RoundView: UIView {
override func layoutSubviews() {
super.layoutSubviews()
self.layer.cornerRadius = 0.5 * self.bounds.size.height
}
}
Then assign that class to the View you want to be round. Xcode will build your new class, and it will show up in Interface Builder like so:

IBInpectable properties for different states when customizing UIButton

I have customised UI button and create some properties with IBInspectable. However, I also need the same property for selected or highlighted state and can be inspected in Interface Builder. I want to know if it can be achieved?
Here is the customized button I created
#IBDesignable
class ImageLabelButton: UIButton{
/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
}
*/
let buttonImgView = UIImageView()
let buttonLabel = UILabel()
// let stackView = UIStackView()
// Override property observors
#IBInspectable
var textColor:UIColor? {
get {
return buttonLabel.textColor
}
set(newValue) {
self.buttonLabel.textColor = newValue
}
}
}
I want to create a IBInspectable property for other states as well. Can it be done? Thanks!
Short answer? No. Interface Builder cannot "process" code.
I have a need to know when my app is in portrait or landscape orientation (various slider controls are on the bottom or right depending on this).
Can I use IB for this? Not if I need to know on an iPad... it's size class is (wR hR) unless the slide out or split screen is there. I can "design" something for each orientation, but even Apple - WWDC'16, Making Apps Adaptive, Part 2 - ended up putting code into viewWillLayoutSubviews() for this.
Put a UIButton on your storyboard. Can you process a tap? Put a UISlider on the storyboard. Can you pan it left or right?
You are asking a design time tool to process run time actions.
So again, you can't make certain button states IBDesignable.

drawRect not called when subclassing UIView and adding it in the interface builder

I am trying to subclass UIView. Code like so:
import UIKit
class CustomView: UIView {
override func drawRect(rect: CGRect) {
// Drawing code
let circlePath = UIBezierPath(ovalInRect: rect)
UIColor.blueColor().setFill()
circlePath.fill()
}
}
I have dragged a UIView onto a UIViewController and set the class to CustomView however the circle doesn't appear (I have set the constraints correctly). Any ideas what I might be doing wrong here? I'm not trying to preview it. Just want to see it when I run the app. Seems I am getting an error in the console too: Unknown class _TtC9MyProject15CustomView in Interface Builder file.
It is likely that the Target Membership for your CustomView.swift file is not set for your app.
In the Project Navigator on the far left, select your file CustomView.swift. Then in the File Navigator on the far right under Target Membership, make sure the box to the left of your app name is checked.

Live Xcode's Interface Builder UIView subclass (IB_DESIGNABLE) without drawRect:

Is it possible to create a UIView subclass that renders live in Xcode (by adding the IB_DESIGNABLE attribute as explained here) but doesn't have a custom drawRect: method?
We have a custom UIView subclass that uses some CAShapeLayers which are added to self.layer for drawing (hence, there's no need to override drawRect:). This class works fine on the App, but won't render on Xcode.
If we replicate the code in drawRect: it works, but we'd prefer to keep the drawing to happen automatically on the layers.
Can this be done?
I also tried doing
- (void)drawRect:(CGRect)rect
{
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextMoveToPoint(currentContext, self.myLayer1.frame.origin.x, self.myLayer1.frame.origin.y);
[self.myLayer1 renderInContext:currentContext];
CGContextMoveToPoint(currentContext, self.myLayer1.frame.origin.x, self.myLayer1.frame.origin.y);
[self.myLayer2 renderInContext:currentContext];
}
which seems to work on the device but not on Xcode's IB.
You can preview UIView subclasses in IB (with the IB_DESIGNABLE macro) even if the drawRect: isn't overridden.
I added your code in XCode 6.1 and added a OEProgressIndicator into a xib file. Then I debugged it (using menu Editor / Debug Selected View ) by setting a breakpoint in your commonProgressIndicatorInit selector.
Here's why you don't see anything in the preview with your current code: when the commonProgressIndicatorInit is invoked (from the initWithFrame:(CGRect)frame constructor), the frame is equal to CGRectZero (x:0 y:0 width:0 height:0) so that your center variable is actually equal to (0, 0) and radius is -1.
On the device, depending on the way the class is used, you may be directly invoked with the proper frame, that's why it may work on the device but not in IB.
To fix this, I would implement the layoutSubviews selector (override it from UIView) to organise properly the sublayers. This selector is going to be invoked when the frame is going to change from CGRectZero to the proper values set in Interface Builder.
I've been using the method - (void)prepareForInterfaceBuilder in order to tell IB to live render a view.
See here: Creating a Live View of a Custom Object
Also, you guys are right that this feature is also available for Objective-C.
You don't necessarily need to use drawRect, you can try using - (void)layoutSubviews, it seems to work. The problem with leaving code in places like - (void)layoutSubviews just for the sake of live rendering is that it may be less performant, etc (for instance you can do a lot of stuff in - (void)awakeFromNib, but that method does not get called from Live Rendering, so just make sure that you do all your set up in - (void)prepareForInterfaceBuilder as well.
Without seeing all your code, it's hard to see what the source of the problem is, but to answer your question, yes, you can use IBInspectable / IBDesignable without needing to implement any other specific method. I have done this for a view that uses many layers and does not do any drawing (uses the nested layers for that).
For a quick test example snippet with rounded corners:
#IBDesignable
class MyView : UIView {
#IBInspectable var cornerRadius:CGFloat {
get { return self.layer.cornerRadius }
set { self.layer.cornerRadius = newValue }
}
#IBInspectable var borderWidth:CGFloat {
get { return self.layer.borderWidth }
set { self.layer.borderWidth = newValue }
}
#IBInspectable var borderColor:UIColor {
get { return UIColor(CGColor: self.layer.borderColor) }
set { self.layer.borderColor = newValue.CGColor }
}
}
For a simple example that does gradients, see this post.
For an explanation on how to debug the live views, refer to WWDC ยง411 at about the 22 minute mark.
The only limitation that I have seen so far is that you can add inspectable properties in class extensions, but they only render properly on the device.

Resources