Add a Border Outside of a Uiview (Instead of Inside)

Add a border outside of a UIView (instead of inside)

Unfortunately, there isn't simply a little property you can set to align the border to the outside. It draws aligned to the inside because the UIViews default drawing operations draw within its bounds.

The simplest solution that comes to mind would be to expand the UIView by the size of the border width when applying the border:

CGFloat borderWidth = 2.0f;

self.frame = CGRectInset(self.frame, -borderWidth, -borderWidth);
self.layer.borderColor = [UIColor yellowColor].CGColor;
self.layer.borderWidth = borderWidth;

Swift make border rof uiimageview outside

Create a UIView and make it slightly larger than the image, then add the image to the center. Setting the background color will make the border a different color.

let border = UIView(frame: CGRect(x: 0, y: 0, width: 251, height: 251))
border.backgroundColor = UIColor.red

let image = UIImageView(frame: CGRect(x: 0, y: 0, width: 250, height: 250))
image.center = border.center
image.image = ...
border.addSubview(image)

How to add a border inside a uiview?

Well there isn't simply a little property you can set to align the border to the outside. It draws aligned to the inside because the UIViews default drawing operations draw within its bounds.

The simplest solution that comes to mind would be to expand the UIView by the size of the border width when applying the border:

CGFloat borderWidth = 2.0f;

self.frame = CGRectInset(self.frame, -borderWidth, -borderWidth);
self.layer.borderColor = [UIColor yellowColor].CGColor;
self.layer.borderWidth = borderWidth;

UIGestureRecognizer works outside of UIView borders instead of inside

Couple issues - without seeing your xib view hierarchy, I can't test this completely, but it should get you on your way.

You are adding the swipe gesture to the window ...

The reason you can't swipe inside the popup view is because the popup view captures the touch gestures. If you set .isUserInteractionEnabled = false you should be able to swipe inside the view.

If you want to swipe only inside the view, check the swipe location and see if the view contains that point.

Along these lines:

@objc private func handleSwipes(_ sender:UISwipeGestureRecognizer) {
// may need to convert touch and frame
let loc = sender.location(in: self)
let r = popupView.frame
if sender.direction == .up, r.contains(loc) {
UIView.animate(withDuration: 0.15, delay: 0.0, options: .curveLinear) {
self.popupView.center.y -= 50
} completion: { _ in
self.popupView.removeFromSuperview()
}
self.isRemovedByTap = true
}
}

You'll need to debug the frame and gesture coordinates to make sure you're checking the correct area.


Edit

To check if the swipe is inside the popupView frame, we have to do a couple things...

Add a new property -- I'll call it yAdjustment -- and then in your animatePopup() func, set that to the popupView's y origin:

var yAdjustment: CGFloat = 0

private func animatePopup() {
UIView.animate(withDuration: 0.15, delay: 0.0, options: .curveLinear) {
self.popupView.center.y += 34
// save the top of the popupView frame
self.yAdjustment = self.popupView.frame.origin.y
} completion: { _ in
UIView.animate(withDuration: 0.15, delay: 10.0, options: .curveLinear) {
self.popupView.center.y -= 50
} completion: { _ in
if !self.isRemovedByTap {
self.popupView.removeFromSuperview()
}
}
}
}

then, change your swipe region testing to this:

@objc private func handleSwipes(_ sender:UISwipeGestureRecognizer) {

// get location of swipe
var loc = sender.location(in: popupView)

// adjust the touch y
loc.y -= (yAdjustment - popupView.frame.origin.y)

// get the view bounds
let r = popupView.bounds

// only do this if
// swipe direct is up
// AND
// swipe location is inside popupView
if sender.direction == .up, r.contains(loc) {
UIView.animate(withDuration: 0.15, delay: 0.0, options: .curveLinear) {
self.popupView.center.y -= 50
} completion: { _ in
self.popupView.removeFromSuperview()
}
self.isRemovedByTap = true
}

}

The reason we have to "correct" the frame...

When you write that chained animation block, this line:

self.popupView.center.y -= 50

is executed immediately -- the animation is simply delayed (by 10-seconds, in this case).

Normally, we would get the touch location in the view's frame and see if it is contained in the bounds.

In this case, though, because the view's frame has already been changed - even though we don't see it yet - we have to compensate for the new location.

outside border for UIImageView

There is no quickway in-built in iOS, there is no margin that you could set on the image layer.

If I were you, I'd develop a new class that inherit from UIView (ex UIImageWithBorderView) and which include a UIImageView and making the "UIImageWithBorderView" bigger than the UIImageView (and think about NOT to autoresize the UIImageView with the UIView parent, otherwise your UIImageView will be stretched, and prevent the UIImageWithBorderView from being smaller than the UIImageView frame), and then add borders to the "UIImageWithBorderView".
This way, your UIImageView will be intact and you'll have a specific, reusable composant for your needs.

Hope it helps !

iOS: Solid Border Outside UIView

Aha! Stitching together aykutt's comment about resizing the image and changing the conentMode, Paul Lynch's answer about resizing images, and rene's (life-saving) answer about what to do your subviews actually aren't laid out in viewDidLayoutSubviews:

override func viewDidLayoutSubviews() {

super.viewDidLayoutSubviews()

self.myContainer.setNeedsLayout()
self.myContainer.layoutIfNeeded()

var width: CGFloat = 4 //the same width used for the border of the imageView
var rect = CGRectInset(imageView.bounds, width, width)
var size = CGSizeMake(rect.width, rect.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
image.drawInRect(CGRectMake(0, 0, size.width, size.height))
var new = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.imageView.contentMode = .Center
self.imageView.image = new

}

Adding border with width to UIView show small background outside

What you are doing is relying on the layer to draw your border and round the corners. So you are not in charge of the result. You gave it a green background, and now you are seeing the background "stick out" at the edge of the border. And in any case, rounding the corners is a really skanky and unreliable way to make a round view. To make a round view, make a round mask.

So, the way to make your badge is to take complete charge of what it is drawn: you draw a green circle in the center of a white background, and mask it all with a larger circle to make the border.

Here is a Badge view that will do precisely what you're after, with no artifact round the outside:

class Badge : UIView {
class Mask : UIView {
override init(frame:CGRect) {
super.init(frame:frame)
self.isOpaque = false
self.backgroundColor = .clear
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
let con = UIGraphicsGetCurrentContext()!
con.fillEllipse(in: CGRect(origin:.zero, size:rect.size))
}
}
let innerColor : UIColor
let outerColor : UIColor
let innerRadius : CGFloat
var madeMask = false
init(frame:CGRect, innerColor:UIColor, outerColor:UIColor, innerRadius:CGFloat) {
self.innerColor = innerColor
self.outerColor = outerColor
self.innerRadius = innerRadius
super.init(frame:frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
let con = UIGraphicsGetCurrentContext()!
con.setFillColor(outerColor.cgColor)
con.fill(rect)
con.setFillColor(innerColor.cgColor)
con.fillEllipse(in: CGRect(
x: rect.midX-innerRadius, y: rect.midY-innerRadius,
width: 2*innerRadius, height: 2*innerRadius))
if !self.madeMask {
self.madeMask = true // do only once
self.mask = Mask(frame:CGRect(origin:.zero, size:rect.size))
}
}
}

I tried this with a sample setting as follows:

let v = Badge(frame: CGRect(x:100, y:100, width:16, height:16), 
innerColor: .green, outerColor: .white, innerRadius: 5)
self.view.addSubview(v)

It looks fine. Adjust the parameters as desired.

Set border outside the bounds of UIImageView

The easiest way would be to draw your image view on another view that has slightly bigger frame than you image view, and set desired color to that view's background color. In your case, background view should be {56,56} in size, and your image view should be centered on that view. And, don't forget to remove layer manipulations. Good Luck!



Related Topics



Leave a reply



Submit