I'm trying to align vertically a text in a view.
For this, I call contentInset function, like this:
override func alignCenterVertical() {
let fittingSize = CGSize(width: bounds.width, height: CGFloat.greatestFiniteMagnitude)
let size = sizeThatFits(fittingSize)
let topOffset = (bounds.size.height - size.height * zoomScale) / 2
let positiveTopOffset = max(1, topOffset)
contentInset = UIEdgeInsets(top: positiveTopOffset, left: 0, bottom: 0, right: 0)
}
But this only work when the value "positiveTopOffset" is negative. (reverse that I want)
I want exactly this comportment but with "positiveTopOffset" positive, like in this part of code here.
When I let the code like this, with "positiveTopOffset" positive, nothing append. Why?
thanks a lot!
I finally found the problem.
I have to add isScrollingEnable = true, like this:
override func alignCenterVertical() {
let fittingSize = CGSize(width: bounds.width, height: CGFloat.greatestFiniteMagnitude)
isScrollingEnabled = true
let size = sizeThatFits(fittingSize)
let topOffset = (bounds.size.height - size.height * zoomScale) / 2
let positiveTopOffset = max(1, topOffset)
contentInset = UIEdgeInsets(top: positiveTopOffset, left: 0, bottom: 0, right: 0)
}
Related
I am trying to place one UIImageView on top of another as follows:
let seatView = SeatView();
let size = UIScreen.main.bounds;
let myimage : UIImage = UIImage(named:playerBoxName)!
let playerSeat = UIImageView(image: myimage);
let width = (size.width * seatWidthFactor) / size.width;
let height = (size.height * seatHeightFactor) / size.width;
seatView.frame = CGRect(x:origin.x, y:origin.y, width: width, height: height);
let cardPairBackImage = UIImage(named:"cardDeck_2");
let cardPairBackImageView = UIImageView(image:cardPairBackImage);
cardPairBackImageView.frame = CGRect(x:origin.x + 40, y:origin.y+20, width: 20, height: 30);
seatView.addSubview(cardPairBackImageView);
seatView.sendSubviewToBack(cardPairBackImageView);
let playerNameLabel = PlayerLabel(frame:CGRect(x: 44, y: 2, width: 54, height: 12 ));
playerNameLabel.setProperties(borderWidth: 0, borderColor: CGColor.init(red: 0, green: 0, blue: 0, alpha: 0));
if !avatarName.contains("Empty") {
playerNameLabel.text = "player";
seatView.addSubview(playerNameLabel);
}
seatView.addSubview(playerSeat);
let avatarImage = UIImage(named:avatarName);
let avatarImageView = UIImageView(image:avatarImage);
seatView.addSubview(avatarImageView);
seatView.bringSubviewToFront(playerNameLabel);
This is the view hierarchy:
The cardPairBackImage always ends up on top of all subviews, but I want that to be pushed to the back of all views (images). What am I doing wrong?
I have a feeling that the method might not be working correctly since you haven't added all the views. What happens if you do this:
let seatView = SeatView();
let size = UIScreen.main.bounds;
let width = (size.width * seatWidthFactor) / size.width;
let height = (size.height * seatHeightFactor) / size.width;
seatView.frame = CGRect(x:origin.x, y:origin.y, width: width, height: height);
let cardPairBackImage = UIImage(named:"cardDeck_2");
let cardPairBackImageView = UIImageView(image:cardPairBackImage);
cardPairBackImageView.frame = CGRect(x:origin.x + 40, y:origin.y+20, width: 20, height: 30);
seatView.addSubview(cardPairBackImageView);
//seatView.sendSubviewToBack(cardPairBackImageView);
let playerNameLabel = PlayerLabel(frame:CGRect(x: 44, y: 2, width: 54, height: 12 ));
playerNameLabel.setProperties(borderWidth: 0, borderColor: CGColor.init(red: 0, green: 0, blue: 0, alpha: 0));
if !avatarName.contains("Empty") {
playerNameLabel.text = "player";
seatView.addSubview(playerNameLabel);
}
let myimage : UIImage = UIImage(named:playerBoxName)!
let playerSeat = UIImageView(image: myimage);
seatView.addSubview(playerSeat);
let avatarImage = UIImage(named:avatarName);
let avatarImageView = UIImageView(image:avatarImage);
seatView.addSubview(avatarImageView);
//Try bringing only one view to the front after all the
//subviews are added and the subviews array is populated
seatView.bringSubviewToFront(playerNameLabel);
I'm trying to make a border like this:
With this code:
self.slot1.layer.cornerRadius = self.slot1.bounds.height / 2
self.slot1.layer.borderWidth = 1.5
self.slot1.layer.borderColor = UIColor.orange.cgColor
It produces:
How can i add a "spacing" between the border and the actual image?
You can achieve this using below extension
extension UIImage {
func imageWithInsets(insets: UIEdgeInsets) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(
CGSize(width: self.size.width + insets.left + insets.right,
height: self.size.height + insets.top + insets.bottom), false, self.scale)
let _ = UIGraphicsGetCurrentContext()
let origin = CGPoint(x: insets.left, y: insets.top)
self.draw(at: origin)
let imageWithInsets = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return imageWithInsets
}
}
Use below code to add space between image and border, i add here 20 you can give your own space
self.slot1.layer.cornerRadius = self.slot1.bounds.height / 2
self.slot1.layer.borderWidth = 1.5
self.slot1.layer.borderColor = UIColor.orange.cgColor
let image = self.slot1.image?.imageWithInsets(insets: UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20))
self.slot1.image = image
Hope this help!
Instead of trying to make space in between, take one UIView inside that put your UIImageView. UIImageView should have less width and height, then add corner radius to both but add border color to UIVIew only.
Your UI should be like this :
Run in playground
import PlaygroundSupport
import UIKit
let iv = UIImageView(frame: CGRect(x: 0.0, y: 0.0, width: 200, height: 200))
PlaygroundPage.current.liveView = iv
iv.backgroundColor = .blue
iv.layer.cornerRadius = 100
iv.layer.borderColor = UIColor.red.cgColor
iv.layer.borderWidth = 5
iv.layer.sublayers?.count
let layer2 = CAShapeLayer()
let newFrame = iv.bounds.insetBy(dx: 7, dy: 7)
layer2.path = UIBezierPath(roundedRect: newFrame, cornerRadius: newFrame.height / 2).cgPath
layer2.frame = iv.bounds
layer2.lineWidth = 5
layer2.strokeColor = UIColor.yellow.cgColor
layer2.fillColor = UIColor.clear.cgColor
iv.layer.addSublayer(layer2)
currently i am using swift 3 and storyboard, googled everything and looked over all stackoverflow similar questions, got nothing so far.
On my example Porject,
my Collection view looks like this
Simulator Screenshot
which is not what i want, i want a grid layout with no spacing at all, i edited the storyboard values ddin't got anything there, so for that i used this code
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
let width = UIScreen.main.bounds.width
layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
layout.itemSize = CGSize(width: width / 2, height: width / 2)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
collectionView!.collectionViewLayout = layout
didn't work either :(
'if let layout = self.collectionView.collectionViewLayout as? UICollectionViewFlowLayout{
let width = UIScreen.main.bounds.width
layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
layout.itemSize = CGSize(width: width / 2, height: width / 2)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
}'
I'm trying to get the center of my view by using the code below, the class being used is from the DTIActivityIndicatorView which add a custom activity indicator to the view.
var midX = CGRectGetMidX(self.view.bounds)
var midY = CGRectGetMidY(self.view.bounds)
let topStoriesActivityIndicator: DTIActivityIndicatorView = DTIActivityIndicatorView(frame: CGRect(x: midX, y: midY, width:80.0, height:80.0))
But the code above is giving me the following result where the activity indicator isn't centered in the middle.
Swift 4 extension:
extension CGRect {
var center: CGPoint { .init(x: midX, y: midY) }
}
let someRect = CGRect(x: 10, y: 10, width: 200, height: 40)
let theCenter = someRect.center // {x 110 y 30}
Swift 3
The following code represent the center of Screen:
let frameSize: CGPoint = CGPoint(x: UIScreen.main.bounds.size.width*0.5,y: UIScreen.main.bounds.size.height*0.5)
Hope this help!
Bounds can be different than how size of the view appears. Try using frame and if it doesn't work try using bounds.
var midX = CGRectGetMidX(self.view.bounds)
var midY = CGRectGetMidY(self.view.bounds)
Also since you are positioning your view in the center and then adding width and height, it appears off as well. You should set the frame like this
let topStoriesActivityIndicator: DTIActivityIndicatorView = DTIActivityIndicatorView(frame: CGRect(x: midX - 80.0, y: midY - 80.0, width:80.0, height:80.0))
Swift 3:
let someRect: CGRect(x: 0, y: 0, width: 10, height: 10)
let midX = someRect.midX
let midY = someRect.midY
Try this :-
var midY = self.view.frame.height / 2
var midX = self.view.frame.width / 2
Swift 5
let frameSize: CGPoint = CGPoint(x:self.view.bounds.midX, y:self.view.bounds.midY)
let frameSize: CGPoint = CGPoint(x:yourView.bounds.midX, y:yourView.bounds.midY)
Or
let frameSize: CGPoint = self.view.center
How about this?
let width = 80
let height = 80
let
topStoriesActivityIndicator: DTIActivityIndicatorView = DTIActivityIndicatorView(frame: CGRect(x: view.bounds.midX - ( width * 0.5), y: view.bounds.midY - ( height * 0.5) , width: width, height: height))
This may be able to help resolve the problem
I'm trying to make a UIButton that has a UIImage on either side (left and right) of the button's title. Ideally, the images would be pinned to the left and right sides of the button, and the title would be centered, but I can live with the images being right next to the title label I suppose. I have been able to add one image, which appears right before the title, but how would I add a second?
I know this is an old question but since no code was provided and someone asked for it I figured I would share my solution for this.
What I did was create a new class which subclasses a UIButton. I made sure that you can see all the changes you do instantly in your interface builder as well. So you can just drag in a UIButton. Specify the class to your own class and it will allow you to set the images and see it being drawn instantly
Here is what I did to achieve this
import UIKit
#IBDesignable
class AddProfilePictureView: UIButton {
#IBInspectable var leftHandImage: UIImage? {
didSet {
leftHandImage = leftHandImage?.withRenderingMode(.alwaysOriginal)
setupImages()
}
}
#IBInspectable var rightHandImage: UIImage? {
didSet {
rightHandImage = rightHandImage?.withRenderingMode(.alwaysTemplate)
setupImages()
}
}
func setupImages() {
if let leftImage = leftHandImage {
self.setImage(leftImage, for: .normal)
self.imageView?.contentMode = .scaleAspectFill
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: self.frame.width - (self.imageView?.frame.width)!)
}
if let rightImage = rightHandImage {
let rightImageView = UIImageView(image: rightImage)
rightImageView.tintColor = COLOR_BLUE
let height = self.frame.height * 0.2
let width = height
let xPos = self.frame.width - width
let yPos = (self.frame.height - height) / 2
rightImageView.frame = CGRect(x: xPos, y: yPos, width: width, height: height)
self.addSubview(rightImageView)
}
}
}
I would break it into two buttons within a collection view- it's very flexible and can work great for something like this.
Add a UIImageView with an image to the button by addSubview and another to the button by setImage, it can be adjusted with titleEdgeInsets and imageEdgeInsets.
if you need a code sample – let me know.
Hope it helps!
Swift 5, XCode 11.6
Please use the below code in your extension or in a custom UIButton class. I have used the below code in my custom class. The function will set left or right image respectively and align the text.
/// Sets a left and right image for a button
/// - Parameters:
/// - right: right image
/// - left: left image
func setImages(right: UIImage? = nil, left: UIImage? = nil) {
if let leftImage = left, right == nil {
setImage(leftImage, for: .normal)
imageEdgeInsets = UIEdgeInsets(top: 5, left: (bounds.width - 35), bottom: 5, right: 5)
titleEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: (imageView?.frame.width)!)
contentHorizontalAlignment = .left
}
if let rightImage = right, left == nil {
setImage(rightImage, for: .normal)
imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: (bounds.width - 35))
titleEdgeInsets = UIEdgeInsets(top: 0, left: (imageView?.frame.width)!, bottom: 0, right: 10)
contentHorizontalAlignment = .right
}
if let rightImage = right, let leftImage = left {
setImage(rightImage, for: .normal)
imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: (bounds.width - 35))
titleEdgeInsets = UIEdgeInsets(top: 0, left: (imageView?.frame.width)!, bottom: 0, right: 10)
contentHorizontalAlignment = .left
let leftImageView = UIImageView(frame: CGRect(x: bounds.maxX - 30,
y: (titleLabel?.bounds.midY)! - 5,
width: 20,
height: frame.height - 10))
leftImageView.image?.withRenderingMode(.alwaysOriginal)
leftImageView.image = leftImage
leftImageView.contentMode = .scaleAspectFit
leftImageView.layer.masksToBounds = true
addSubview(leftImageView)
}
}
Usage:
vegaButton.setImage(right: myImage) // for right image
vegaButton.setImage(left: myImage) // for left image
vegaButton.setImage(right: myImage, left: myImage) // for both images.