Hey I implemented marquee label into my project with cocoa pods but have been unsuccessful in getting it to rotate.
let newsFeed: MarqueeLabel = MarqueeLabel(
frame: CGRect(x:15, y:66, width:28, height:159))
newsFeed.textAlignment = .right newsFeed.text = "TEXT"
self.view.addSubview(newsFeed)
newsFeed.transform = CGAffineTransform(
rotationAngle: CGFloat(-(Double.pi / 2.0)))
newsFeed.frame = CGRect(x:15, y:66, width:28, height:159)
You should:
Set the height and width of your field to the unrotated height and
width when you create it:
Not try to manipulate the frame once you've changed the view's
transform. Instead you should set the view's center: To quote Apple's
docs on UIView.transform:
Warning When the value of this property is anything other than the
identity transform, the value in the frame property is undefined and
should be ignored.
I don't know what a MarqueeLabel is, but this code using a vanilla UILabel works:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let startingFrameRect = CGRect(x:15, y:66, width:159, height:28)
let newsFeed = UILabel(
//Create the label wide and short as if it is not rotated.
frame: startingFrameRect)
newsFeed.text = "Some Text"
self.view.addSubview(newsFeed)
newsFeed.transform = CGAffineTransform(
rotationAngle: CGFloat(-(Double.pi / 2.0)))
//Add a border so you can see the label's rotated frame
newsFeed.layer.borderWidth = 1.0
//Adjust the view's center based on it's origin, but exchanging height and width
newsFeed.center = CGPoint (x: startingFrameRect.origin.x + startingFrameRect.size.height / 2,
y: startingFrameRect.origin.y + startingFrameRect.size.width / 2)
//Also add a view to show where the unrotated view would land.
let boxView = UIView(frame: startingFrameRect)
boxView.layer.borderWidth = 1.0
boxView.layer.borderColor = UIColor.blue.cgColor
self.view.addSubview(boxView)
}
}
Related
I've been trying unsuccessfully to vertically center my text in my UITextView as soon as my app starts up. No matter what I've tried the text just appears at the top of the text view like it normally would. Here is a photo.
The only time the text centers correctly is when I type it, this was done by using an observer. Here is the code I'm using to center my text in viewDidLoad, I've tried 2 methods, neither worked.
extension UITextView {
func centerText() {
self.textAlignment = .center
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)
contentOffset.y = -positiveTopOffset
}
func alignTextVerticallyInContainer() {
var topCorrect = (self.bounds.size.height - self.contentSize.height * self.zoomScale) / 2
topCorrect = topCorrect < 0.0 ? 0.0 : topCorrect;
self.contentInset.top = topCorrect
}
}
I would call these methods in my viewDidLoad like this: self.goalTextView.centerText() or self.goalTextView.alignTextVerticallyInContainer(). So now that you've seen what I've tried so far, anyone have any idea how to force the text in the textview to be centered vertically on startup? Any help would be appreciated.
I have an image which is set inside a scroll view, though I have set the frame of the scrollView to fixed height and width as shown below, the image goes beyond the bounds (see below picture).
How can I limit the picture to fit inside the scrollView.
imageScrollView.frame = CGRect(x: 0, y: 0, width: viewWidth, height: viewHeight-50)
imageScrollView.clipsToBounds = true // Has no affect on the image
Do you have a reference to the UIImageView? If so, then set its content mode to aspect fit. Like this:
theImageView.contentMode = .scaleAspectFit
The clipsToBounds you set only covers up any parts of child views that are sticking out of the bounds of the parent view, so that's why it doesn't do anything for you.
OR if you're using Interface Builder, set this option:
So, what if you don't have the reference to the UIImageView?...
You could iterate through the subviews of your scroll view, and whenever it finds a UIImageView, you can set the content mode like that. Something like:
//This is off the top of my head, so my filtering may not be right...
//This is also a one and done solution if you've got a lot of images in your scroll view
for anImgVw in imageScrollView.subviews.filter({$0.isKind(of: UIImageView.self)})
{
anImgVw.contentMode = .scaleAspectFit
}
Otherwise, I'm not sure if it's possible without a reference to the UIImageView.
The library you are using is coded to match the scaling to the device orientation. So, if the image orientation doesn't match the view orientation, you end up with the image not quite fitting in your scroll view.
You'll need to edit the ImageScrollView.swift source file. Assuming you're using the same version that is currently at the link you provided ( https://github.com/huynguyencong/ImageScrollView ), change the setMaxMinZoomScalesForCurrentBounds() function as follows:
fileprivate func setMaxMinZoomScalesForCurrentBounds() {
// calculate min/max zoomscale
let xScale = bounds.width / imageSize.width // the scale needed to perfectly fit the image width-wise
let yScale = bounds.height / imageSize.height // the scale needed to perfectly fit the image height-wise
// fill width if the image and phone are both portrait or both landscape; otherwise take smaller scale
//let imagePortrait = imageSize.height > imageSize.width
//let phonePortrait = bounds.height >= bounds.width
//var minScale = (imagePortrait == phonePortrait) ? xScale : min(xScale, yScale)
//
// just take the min scale, so the image will completely fit regardless of orientation
var minScale = min(xScale, yScale)
let maxScale = maxScaleFromMinScale*minScale
// don't let minScale exceed maxScale. (If the image is smaller than the screen, we don't want to force it to be zoomed.)
if minScale > maxScale {
minScale = maxScale
}
maximumZoomScale = maxScale
minimumZoomScale = minScale * 0.999 // the multiply factor to prevent user cannot scroll page while they use this control in UIPageViewController
}
you can use the screenHeight rather than the viewHeight
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenSize.width
let screenHeight = screenSize.height
imageScrollView.frame = CGRect(x: 0, y: 0, width: viewWidth, height: screenHeight-50)
Currently, I am working with UIProgressView where I need to change the height of the UIProgressView. I achieve through below code.
extension UIProgressView {
#IBInspectable var barHeight : CGFloat {
get {
return transform.d * 2.0
}
set {
// 2.0 Refers to the default height of 2
let heightScale = newValue / 2.0
let c = center
transform = CGAffineTransform(scaleX: 1.0, y: heightScale)
center = c
self.layer.cornerRadius = 20.0
}
}
}
but when I set cornerRadius to UIProgressView not get affected.
You also need to tell that to not draw outside its bounds, after setting the cornerRadius.
//this is on the layer level
self.progressView.layer.masksToBounds = true
//another way is to use clipToBounds
self.progressView.clipsToBounds = true
I'm trying to create a game that generates labels randomly on the screen, but the entire word must be inside the screen. I also have a textfield in the screen that I'm intending to put the words beneath.
I have a function for adding a label, and another for making sure It's inside the borders.
func addWord(word: String) {
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = UInt32(screenSize.width)
let screenHeight = UInt32(screenSize.height)
let label = UILabel()
label.text = word
label.font = UIFont.systemFontOfSize(32)
label.sizeToFit()
label.backgroundColor = UIColor.whiteColor()
let x = CGFloat(arc4random_uniform(screenWidth))
let y = CGFloat(arc4random_uniform(screenHeight))
label.center = CGPointMake(x, y)
label.center = checkBounds(label, minX: 0, maxX: CGFloat(screenWidth), minY: (newWordsTextField.bounds.origin.y+newWordsTextField.bounds.maxY), maxY: CGFloat(screenHeight))
view.addSubview(label)
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(ViewController.handlePanGesture(_:)))
label.addGestureRecognizer(panGesture)
label.userInteractionEnabled = true
}
func checkBounds(label: UILabel, minX: CGFloat, maxX: CGFloat, minY: CGFloat, maxY: CGFloat)->CGPoint{
let borders = label.bounds
var newCenter = label.center
if borders.minX < minX {
newCenter.x = newCenter.x + (minX-borders.minX)
}
if borders.maxX > maxX {
newCenter.x = newCenter.x-(borders.maxX-maxX)
}
if borders.minY < minY {
newCenter.y = newCenter.y + (minY-borders.minY)
}
if borders.maxY > maxY {
newCenter.y = newCenter.y-(borders.maxY-maxY)
}
return newCenter
}
but for some reason the labels keep getting out of the boundaries even though the function should've made sure that wouldn't happen. I'm kind of new to swift and it's the first time I'm trying something like this, help please, what am I doing wrong?
If you're using Auto Layout (you almost certainly are because it's the default and you have to turn it off manually) then the frame and center of your view objects gets overridden by Auto Layout constraints (either once you define or ones the system creates automatically.)
If you're going to add views manually then you need to add constraints as well. That should fix your problem. I suggest googling "add UIViews and constraints through code" or something similar to find tutorials on how it's done (or better yet just add the views in your storyboard and mark them as hidden until you need them.
I'm trying to center my subview with a button in itssuperview. So I want the center of the subview be the center of the superview. I'm trying that with following code:
override func viewDidLoad() {
self.view.backgroundColor = UIColor.redColor()
var menuView = UIView()
var newPlayButton = UIButton()
//var newPlayImage = UIImage(named: "new_game_button_5cs")
var newPlayImageView = UIImageView(image: UIImage(named: "new_game_button_5cs"))
newPlayButton.frame = CGRectMake(0, 0, newPlayImageView.frame.width, newPlayImageView.frame.height)
newPlayButton.setImage(newPlayImage, forState: .Normal)
newPlayButton.backgroundColor = UIColor.whiteColor()
menuView.center = self.view.center
menuView.center = CGPointMake(self.view.bounds.size.width / 2, self.view.bounds.size.height / 2)
menuView.backgroundColor = UIColor.whiteColor()*/
menuView.addSubview(newPlayButton)
}
Unfortunately it doesent seem to work as this is the result:
UIView *subview = your View To Be Centered In Its SuperView;
UIView *superView = subview.superview;
subview.center = [superView convertPoint:superView.center
fromView:superView.superview];
If view is nil(on fromView:), this method instead converts from window base coordinates. Otherwise, both view and the receiver must belong to the same UIWindow object.
NOTE: If you use the auto layout stuff, then you have to change the constraints . not the frame or center.
Good Luck :)
Try removing your view width from your superview width, e.g.:
var width: CGFloat = (self.view.bounds.size.width / 2)
// (here goes your view width that you want centralize)
menuView.center = CGPointMake(width, self.view.bounds.size.height / 2)
My working code
vRate = superview
rcRating = view ( that I want to centralize in vRate )
self.rcRating = AMRatingControl(location: CGPoint(x: 0, y: 0), andMaxRating: 5)
self.vRate.addSubview(self.rcRating)
var width: CGFloat = (self.vRate.bounds.size.width / 2) - self.rcRating.bounds.size.width
self.rcRating.center = CGPointMake(width, self.vRate.bounds.size.height / 2)