Add tooltip pointer in Swift iOS - ios

On button click, I want to create tooltip.
and now I am getting a rectangle.
How do I add a pointer as below image?
Expected:
Current:
Following is the code where I am trying to create tooltip like view
var ToolTipView = UIView()
func tooltip(){
for view in self.ToolTipView.subviews {
view.removeFromSuperview()
}
ToolTipView.removeFromSuperview()
ToolTipView.frame = CGRect(x:50, y:self.view.bounds.height-150, width:100, height:50)
ToolTipView.backgroundColor = UIColor(red:0, green:0, blue:0, alpha:0.7)
ToolTipView.layer.cornerRadius = 5.0
let txtLabel = UILabel(frame: CGRect(x:0, y:2, width:100, height:50))
txtLabel.text = "Click"
txtLabel.textAlignment = NSTextAlignment.Center
txtLabel.textColor = UIColor(red:1, green:1, blue:1, alpha:1)
txtLabel.font = UIFont(name:"HelveticaNeue", size: 16)
self.ToolTipView.addSubview(txtLabel)
self.view.addSubview(ToolTipView)
self.view.bringSubviewToFront(ToolTipView)
}

Try CocoaControls for a list of libraries developed for you. Simply search your query and there will be a list of controls. Chose one of them, and select download source. It will take to Github, download or use pod for that control and enjoy :)
Here is link to your desired query as example.

How about this?
extension UIView {
func displayTooltip(_ message: String, completion: (() -> Void)? = nil) {
let tooltipBottomPadding: CGFloat = 12
let tooltipCornerRadius: CGFloat = 6
let tooltipAlpha: CGFloat = 0.95
let pointerBaseWidth: CGFloat = 14
let pointerHeight: CGFloat = 8
let padding = CGPoint(x: 18, y: 12)
let tooltip = UIView()
let tooltipLabel = UILabel()
tooltipLabel.text = " \(message) "
tooltipLabel.font = UIFont.systemFont(ofSize: 12)
tooltipLabel.contentMode = .center
tooltipLabel.textColor = .white
tooltipLabel.layer.backgroundColor = UIColor(red: 44 / 255, green: 44 / 255, blue: 44 / 255, alpha: 1).cgColor
tooltipLabel.layer.cornerRadius = tooltipCornerRadius
tooltip.addSubview(tooltipLabel)
tooltipLabel.translatesAutoresizingMaskIntoConstraints = false
tooltipLabel.bottomAnchor.constraint(equalTo: tooltip.bottomAnchor, constant: -pointerHeight).isActive = true
tooltipLabel.topAnchor.constraint(equalTo: tooltip.topAnchor).isActive = true
tooltipLabel.leadingAnchor.constraint(equalTo: tooltip.leadingAnchor).isActive = true
tooltipLabel.trailingAnchor.constraint(equalTo: tooltip.trailingAnchor).isActive = true
let labelHeight = message.height(withWidth: .greatestFiniteMagnitude, font: UIFont.systemFont(ofSize: 12)) + padding.y
let labelWidth = message.width(withHeight: .zero, font: UIFont.systemFont(ofSize: 12)) + padding.x
let pointerTip = CGPoint(x: labelWidth / 2, y: labelHeight + pointerHeight)
let pointerBaseLeft = CGPoint(x: labelWidth / 2 - pointerBaseWidth / 2, y: labelHeight)
let pointerBaseRight = CGPoint(x: labelWidth / 2 + pointerBaseWidth / 2, y: labelHeight)
let pointerPath = UIBezierPath()
pointerPath.move(to: pointerBaseLeft)
pointerPath.addLine(to: pointerTip)
pointerPath.addLine(to: pointerBaseRight)
pointerPath.close()
let pointer = CAShapeLayer()
pointer.path = pointerPath.cgPath
pointer.fillColor = UIColor(red: 44 / 255, green: 44 / 255, blue: 44 / 255, alpha: 1).cgColor
tooltip.layer.addSublayer(pointer)
(superview ?? self).addSubview(tooltip)
tooltip.translatesAutoresizingMaskIntoConstraints = false
tooltip.bottomAnchor.constraint(equalTo: topAnchor, constant: -tooltipBottomPadding + pointerHeight).isActive = true
tooltip.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
tooltip.heightAnchor.constraint(equalToConstant: labelHeight + pointerHeight).isActive = true
tooltip.widthAnchor.constraint(equalToConstant: labelWidth).isActive = true
tooltip.alpha = 0
UIView.animate(withDuration: 0.2, animations: {
tooltip.alpha = tooltipAlpha
}, completion: { _ in
UIView.animate(withDuration: 0.5, delay: 0.5, animations: {
tooltip.alpha = 0
}, completion: { _ in
tooltip.removeFromSuperview()
completion?()
})
})
}
}
with String extensions:
extension String {
func width(withHeight constrainedHeight: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: constrainedHeight)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil)
return ceil(boundingBox.width)
}
func height(withWidth constrainedWidth: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: constrainedWidth, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil)
return ceil(boundingBox.height)
}
}
Usage:
clickMeButton.displayTooltip("Clicked!")
Result:
Dark gray tooltip with text shown over button

class MyViewController: UIViewController, UIPopoverPresentationControllerDelegate {
#objc func expandClicked(sender: UIButton!) {
let vc = UIViewController()
vc.view.backgroundColor = .white
display(viewcontroller: vc, size: CGSize(width: 150, height: 40), sender: sender)
}
func display(viewcontroller: UIViewController, size: CGSize, sender: UIView) {
let controller = viewcontroller
controller.modalPresentationStyle = .popover
controller.popoverPresentationController?.delegate = self
controller.preferredContentSize = size
let presentationController = controller.popoverPresentationController!
presentationController.sourceView = sender
presentationController.sourceRect = sender.bounds
presentationController.backgroundColor = .white
let buttonPosition = CGPoint(x: sender.bounds.minX, y: sender.bounds.maxY)
let p = sender.convert(buttonPosition, to: transactionTableView)
if (transactionTableView.bounds.maxY - p.y) > 70 {
presentationController.permittedArrowDirections = .up
} else {
presentationController.permittedArrowDirections = .down
}
self.present(controller, animated: true)
}
public func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.none
}
}

Related

How to Change uitextfield leftView image tintColor on editing

I'm trying to achieve UITextField editing or not editing style like this:
But the trickiest part for me is How to change that left image tint color. I have achieved this so far:
My code:
UITextField
lazy var email: UITextField = {
let name = UITextField()
name.layer.cornerRadius = 17.5
name.layer.borderColor = UIColor(red: 0.55, green: 0.61, blue: 0.69, alpha: 0.5).cgColor
name.layer.borderWidth = 1.5
name.placeholder = "Email"
name.font = UIFont.systemFont(ofSize: 15)
name.textColor = UIColor(red: 0.55, green: 0.61, blue: 0.69, alpha: 1)
name.backgroundColor = .clear
name.leftViewMode = UITextFieldViewMode.always
name.delegate = self
name.translatesAutoresizingMaskIntoConstraints = false
return name
}()
leftImage func:
func addLeftImageTo(txtField: UITextField, andImage img: UIImage) {
let leftView = UIView(frame: CGRect(x: 0, y: 0, width: 42.75, height: 40))
let centerX: CGFloat = (leftView.frame.midX) - (img.size.width / 2)
let centerY: CGFloat = (leftView.frame.midY) - (img.size.height / 2)
let leftImageView = UIImageView(frame: CGRect(x: centerX + 2 , y: centerY - 1, width: img.size.width, height: img.size.height))
leftImageView.contentMode = .scaleAspectFit
leftImageView.image = img
leftView.addSubview(leftImageView)
txtField.leftView = leftView
txtField.leftViewMode = .always
}
Adding leftImages:
let emailLeftImg = UIImage(named: "ic_txt_field_email")
addLeftImageTo(txtField: email, andImage: emailLeftImg!)
let passwordLeftImg = UIImage(named: "ic_txt_field_password")
addLeftImageTo(txtField: password, andImage: passwordLeftImg!)
editingBegains and Ending:
func textFieldDidBeginEditing(_ textField: UITextField) {
self.setTextBorder(textField: textField, color: UIColor.white, borderColor: UIColor.white, isSelected: true)
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.setTextBorder(textField: textField, color: UIColor.clear, borderColor: UIColor(red: 0.55, green: 0.61, blue: 0.69, alpha: 0.5), isSelected: false)
}
func setTextBorder(textField: UITextField, color: UIColor, borderColor: UIColor, isSelected: Bool) {
textField.backgroundColor = color
textField.layer.borderColor = borderColor.cgColor
textField.tintColor = UIColor(red: 1.0, green: 0.2, blue: 0.33, alpha: 1)
textField.layer.masksToBounds = false
if isSelected == true {
textField.layer.shadowRadius = 3.0
textField.layer.shadowColor = UIColor.black.cgColor
textField.layer.shadowOffset = CGSize(width: 0, height: 2)
textField.layer.shadowOpacity = 0.125
} else {
textField.layer.shadowRadius = 0
textField.layer.shadowColor = UIColor.clear.cgColor
textField.layer.shadowOffset = CGSize(width: 0, height: 0)
textField.layer.shadowOpacity = 0
}
}
I had tried adding this code to change Image color but it didn't work.
var picTintColor: Bool = false
In LeftImage func:
if picTintColor == true {
leftImageView.image = img.withRenderingMode(.alwaysTemplate)
leftImageView.tintColor = .blue
} else {
leftImageView.image = img
}
And in editingBegains and Ending func:
if isSelected == true {
picTintColor = true
} else {
picTintColor = false
}
I'm a complete noob in IOS programming so thanks for your patience and sorry for my bad english. Thanks!
According the code ,it actually can not pass isSelected signal to the leftImageView,maybe leftImageView get in laster is not the earlier ,or the signal not pass successly.
I suggest that a easy way to do, just in editingBegains and Ending: to do what you want change the imageview,like this:
func textFieldDidBeginEditing(_ textField: UITextField) {
let emailLeftImg = UIImage(named: "ic_txt_field_email")
addLeftImageTo(txtField: email, andImage: emailLeftImg!)
}
func addLeftImageTo(txtField: UITextField, andImage img: UIImage) {
let leftView = UIView(frame: CGRect(x: 0, y: 0, width: 42.75, height: 40))
let centerX: CGFloat = (leftView.frame.midX) - (img.size.width / 2)
let centerY: CGFloat = (leftView.frame.midY) - (img.size.height / 2)
let leftImageView = UIImageView(frame: CGRect(x: centerX + 2 , y: centerY - 1, width: img.size.width, height: img.size.height))
leftImageView.contentMode = .scaleAspectFit
if picTintColor == true {
leftImageView.image = img.withRenderingMode(.alwaysTemplate)
leftImageView.tintColor = .blue
} else {
leftImageView.image = img
}
leftView.addSubview(leftImageView)
txtField.leftView = leftView
txtField.leftViewMode = .always
}
and in end delgate method ,just do that ,you can try this way to test.Hope to help you.

Custom view doesn't appear for the first time swift

When user open my app for the first time, my custom view doesn't appear. But the next time it works fine.
I am calling this view when user taps on button.
let menu = MenuView(image: image, title: "text", buttons: buttons)
menu.show(animated: true)
Custom View code
class MenuView: UIView, Menu {
var background = UIView()
var blackOverlay = UIView()
convenience init(image: UIImage, title: String, buttons: [UIButton]) {
self.init(frame: UIScreen.main.bounds)
setupView(image: image, title: title, buttons: buttons)
}
#objc func cancelTapped() {
hide(animated: true)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupView(image: UIImage, title: String, buttons: [UIButton]) {
blackOverlay.backgroundColor = UIColor.black.withAlphaComponent(0.5)
blackOverlay.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
addSubview(blackOverlay)
let backgroundWidth = self.frame.width - CGFloat(80.0)
let imageView = UIImageView(frame: CGRect(x: (backgroundWidth/2)-17, y: 40, width: 34, height: 34))
imageView.image = image
imageView.contentMode = .center
background.addSubview(imageView)
let titleLabel = UILabel()
let stringHeight = title.stringHeight + 14
titleLabel.frame = CGRect(x: background.center.x+8, y: 100, width: backgroundWidth-16, height: stringHeight)
titleLabel.font = UIFont.systemFont(ofSize: 15, weight: .regular)
titleLabel.text = title
titleLabel.textAlignment = .center
titleLabel.numberOfLines = 0
background.addSubview(titleLabel)
var newHeight: CGFloat = 0
for i in 0...buttons.count-1 {
buttons[i].frame.origin = CGPoint(x: 0, y: titleLabel.frame.height + 125 + CGFloat(i*50))
buttons[i].frame.size = CGSize(width: backgroundWidth, height: 50)
buttons[i].setTitleColor(.gingerColor, for: .normal)
buttons[i].setTitleColor(UIColor.gingerColor.withAlphaComponent(0.5), for: .highlighted)
buttons[i].titleLabel?.textAlignment = .center
newHeight+=buttons[i].frame.height
let separator = UIView()
separator.frame.origin = CGPoint(x: 0, y: titleLabel.frame.height + 125 + CGFloat(i*50))
separator.frame.size = CGSize(width: frame.width, height: 1)
separator.backgroundColor = UIColor(hexString: "dedede")
background.addSubview(separator)
if i == buttons.count-1 {
buttons[i].setTitleColor(UIColor(hexString: "9E9E9E"), for: .normal)
}
buttons[i].addTarget(self, action: #selector(self.cancelTapped), for: .touchUpInside)
background.addSubview(buttons[i])
}
background.frame.origin = CGPoint(x: center.x, y: frame.height)
background.frame.size = CGSize(width: frame.width-80, height: 90 + titleLabel.frame.height+imageView.frame.height + CGFloat(newHeight))
background.backgroundColor = .white
background.layer.cornerRadius = 16
background.layer.masksToBounds = true
addSubview(background)
}
}
and my custom view protocol & extension code:
protocol Menu {
func show(animated: Bool)
func hide(animated: Bool)
var blackOverlay: UIView { get }
var background: UIView { get }
}
extension Menu where Self: UIView {
func show(animated: Bool) {
self.blackOverlay.alpha = 0
self.background.alpha = 0
self.blackOverlay.center = self.center
self.background.center = CGPoint(x: self.center.x, y: self.frame.height+self.background.frame.height/2)
UIApplication.shared.delegate?.window??.rootViewController?.view.addSubview(self)
if animated {
UIView.animate(withDuration: 0.33, animations: {
self.blackOverlay.alpha = 1
self.background.alpha = 1
})
UIView.animate(withDuration: 0.33, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 10, options: UIViewAnimationOptions(rawValue: 0), animations: {
self.background.center = self.center
}, completion: { (completed) in
print("completed is \(completed)")
})
} else {
self.blackOverlay.alpha = 1
self.background.alpha = 1
self.background.center = self.center
}
}
func hide(animated: Bool) {
if animated {
UIView.animate(withDuration: 0.33, animations: {
self.blackOverlay.alpha = 0
self.background.alpha = 0
})
UIView.animate(withDuration: 0.33, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 10, options: UIViewAnimationOptions(rawValue: 0), animations: {
self.background.center = CGPoint(x: self.center.x, y: self.frame.height + self.background.frame.height/2)
}, completion: { (completed) in
self.removeFromSuperview()
})
} else {
self.removeFromSuperview()
}
}
}
As you can see I have a parameter completed in completion animation block, it returns false for the first time. All subsequent times it returns false
I found my mistake.
I tried to present my custom view controller above rootController. But, for the very first time user's rootcontroller is the first screen of onboarding. So, my custom view tried to be shown on another controller.

UIBarButtonItem Frame changes after Rotation animation

I am facing issue in frame while doing rotation animation in custom UIBarButtonItem.
My code is as follow:
class ViewController: UIViewController {
var bellIcon: UIBarButtonItem = UIBarButtonItem()
override func viewDidLoad() {
super.viewDidLoad()
setupBellButton()
}
func setupBellButton(){
let icon = UIImage(named: "Bell.png")
let iconSize = CGRect(origin: CGPoint.zero, size: icon!.size)
let iconButton = UIButton(frame: iconSize)
iconButton.setBackgroundImage(icon, for: .normal)
let badgeView = UIView(frame: CGRect(origin: CGPoint(x: iconButton.frame.maxX-10, y: iconButton.frame.minX), size: CGSize(width: 10, height: 10)))
badgeView.layer.cornerRadius = 5
badgeView.layer.borderColor = UIColor.red.cgColor
badgeView.backgroundColor = UIColor.red
badgeView.layer.masksToBounds = true
badgeView.clipsToBounds = true
let btnContainer = UIView(frame: CGRect(origin: CGPoint.zero, size: icon!.size))
btnContainer.addSubview(iconButton)
btnContainer.addSubview(badgeView)
badgeView.transform = CGAffineTransform(scaleX: 0, y: 0)
UIView.animate(withDuration: 1) {
badgeView.transform = CGAffineTransform(scaleX: 1, y: 1)
}
bellIcon.customView = btnContainer
iconButton.addTarget(self, action:#selector(bellIconTapped), for: .touchUpInside)
navigationItem.rightBarButtonItem = bellIcon
bellIcon.customView?.backgroundColor = UIColor.purple
}
#IBAction func bellIconTapped(_ sender: Any) {
UIView.animate(withDuration: 0.3, animations: {
self.bellIcon.customView!.transform = CGAffineTransform(rotationAngle: -0.4)
}) { (true) in
UIView.animate(withDuration: 0.3, animations: {
self.bellIcon.customView!.transform = CGAffineTransform(rotationAngle: 0.4)
}, completion: { (true) in
UIView.animate(withDuration: 0.4, animations: {
self.bellIcon.customView!.transform = CGAffineTransform.identity
})
})
}
}
}
Thanks in advance!!!
I have resolved the above issue for both iOS 10 and 11 by simply adding the constant to the 'bellIcon.customView'
I have added following code at the end of the 'setupBellButton()'
bellIcon.customView?.translatesAutoresizingMaskIntoConstraints = false
let widthConstraint = bellIcon.customView?.widthAnchor.constraint(equalToConstant: 25.0)
let heightConstraint = bellIcon.customView?.heightAnchor.constraint(equalToConstant: 25.0)
bellIcon.customView?.addConstraints([widthConstraint!, heightConstraint!])
Happy Coding!!!

How to set CAEmitterLayer background transparent?

var emitter = CAEmitterLayer()
emitter.emitterPosition = CGPoint(x: self.view.frame.size.width / 2, y: -10)
emitter.emitterShape = kCAEmitterLayerLine
emitter.emitterSize = CGSize(width: self.view.frame.size.width, height: 2.0)
emitter.emitterCells = generateEmitterCells()
self.view.layer.addSublayer(emitter)
here, CAEmitterLayer covers my view... the content of self.view not visible..
Ref. code : https://oktapodi.github.io/2017/05/08/particle-effects-in-swift-using-caemitterlayer.html
I want to set this animation on my view.
I don't know if I understand you correct, but if this is the effect you are looking for:
Then you need to:
Add a "container view" for your your emitter to live in
Create an outlet for that view
set clipsToBounds to true for your container view
Here is my ViewController which produced the above screenshot
import UIKit
enum Colors {
static let red = UIColor(red: 1.0, green: 0.0, blue: 77.0/255.0, alpha: 1.0)
static let blue = UIColor.blue
static let green = UIColor(red: 35.0/255.0 , green: 233/255, blue: 173/255.0, alpha: 1.0)
static let yellow = UIColor(red: 1, green: 209/255, blue: 77.0/255.0, alpha: 1.0)
}
enum Images {
static let box = UIImage(named: "Box")!
static let triangle = UIImage(named: "Triangle")!
static let circle = UIImage(named: "Circle")!
static let swirl = UIImage(named: "Spiral")!
}
class ViewController: UIViewController {
#IBOutlet weak var emitterContainer: UIView!
var emitter = CAEmitterLayer()
var colors:[UIColor] = [
Colors.red,
Colors.blue,
Colors.green,
Colors.yellow
]
var images:[UIImage] = [
Images.box,
Images.triangle,
Images.circle,
Images.swirl
]
var velocities:[Int] = [
100,
90,
150,
200
]
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
view.backgroundColor = UIColor.red
emitter.emitterPosition = CGPoint(x: emitterContainer.frame.size.width / 2, y: -10)
emitter.emitterShape = kCAEmitterLayerLine
emitter.emitterSize = CGSize(width: emitterContainer.frame.size.width, height: 2.0)
emitter.emitterCells = generateEmitterCells()
emitterContainer.layer.addSublayer(emitter)
emitterContainer.clipsToBounds = true
}
private func generateEmitterCells() -> [CAEmitterCell] {
var cells:[CAEmitterCell] = [CAEmitterCell]()
for index in 0..<16 {
let cell = CAEmitterCell()
cell.birthRate = 4.0
cell.lifetime = 14.0
cell.lifetimeRange = 0
cell.velocity = CGFloat(getRandomVelocity())
cell.velocityRange = 0
cell.emissionLongitude = CGFloat(Double.pi)
cell.emissionRange = 0.5
cell.spin = 3.5
cell.spinRange = 0
cell.color = getNextColor(i: index)
cell.contents = getNextImage(i: index)
cell.scaleRange = 0.25
cell.scale = 0.1
cells.append(cell)
}
return cells
}
private func getRandomVelocity() -> Int {
return velocities[getRandomNumber()]
}
private func getRandomNumber() -> Int {
return Int(arc4random_uniform(4))
}
private func getNextColor(i:Int) -> CGColor {
if i <= 4 {
return colors[0].cgColor
} else if i <= 8 {
return colors[1].cgColor
} else if i <= 12 {
return colors[2].cgColor
} else {
return colors[3].cgColor
}
}
private func getNextImage(i:Int) -> CGImage {
return images[i % 4].cgImage!
}
}
Hope that helps you.
It is working fine check output of my simulator. Background images are added from storyboard and blue color is done by code. Still working fine.
OUTPUT:
You can fix your problem by changing the way you add the layer right now your adding it on top of everything which sometimes hide other layers and view objects.
change
self.view.layer.addSublayer(emitter)
To
self.view.layer.insertSublayer(emitter, at: 0)
Hello change emitterPosition X of each like below:-
let emitter1 = Emitter.getEmitter(with: #imageLiteral(resourceName: "img_ribbon_4"), directionInRadian: (180 * (.pi/180)), velocity: 50)
emitter1.emitterPosition = CGPoint(x: self.view.frame.width / 3 , y: 0)
emitter1.emitterSize = CGSize(width: self.view.frame.size.width, height: 2.0)
self.view.layer.addSublayer(emitter1)
let emitter2 = Emitter.getEmitter(with: #imageLiteral(resourceName: "img_ribbon_6"), directionInRadian: (180 * (.pi/180)), velocity: 80)
emitter2.emitterPosition = CGPoint(x: self.view.frame.width / 2, y: 0)
emitter2.emitterSize = CGSize(width: self.view.frame.size.width, height: 2.0)
self.view.layer.addSublayer(emitter2)
I hope it will help you,
thank you.

How to make image weight and height fill screen in Swift Xcode?

I found a code to make slide in swift, but cant find, how to make the IMAGE fill the whole screen.
Could you help?
here is the screenshot of slider, and you will see the anchors I placed on it to show you, the whole screen.
and here is the code of it;
import UIKit
class OnboardingController: UIViewController, UIScrollViewDelegate {
let backgroundColor = UIColor(red: 241.0/255.0, green: 196.0/255.0, blue: 15.0/255.0, alpha: 1.0)
let slides = [
[ "image": "book4page1.png"],
[ "image": "book4page2.png"],
[ "image": "book4page3.png"],
]
let screen: CGRect = UIScreen.mainScreen().bounds
var scroll: UIScrollView?
var dots: UIPageControl?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = backgroundColor
scroll = UIScrollView(frame: CGRect(x: 0.0, y: 0.0, width: screen.width, height: screen.height * 0.9))
scroll?.showsHorizontalScrollIndicator = false
scroll?.showsVerticalScrollIndicator = false
scroll?.pagingEnabled = true
view.addSubview(scroll!)
if (slides.count > 1) {
dots = UIPageControl(frame: CGRect(x: 0.0, y: screen.height * 0.875, width: screen.width, height: screen.height * 0.05))
dots?.numberOfPages = slides.count
view.addSubview(dots!)
}
for var i = 0; i < slides.count; ++i {
if let image = UIImage(named: slides[i]["image"]!) {
let imageView: UIImageView = UIImageView(frame: getFrame(image.size.width, iH: image.size.height, slide: i, offset: screen.height * 0.15))
imageView.image = image
scroll?.addSubview(imageView)
}
if let text = slides[i]["text"] {
let textView = UITextView(frame: CGRect(x: screen.width * 0.05 + CGFloat(i) * screen.width, y: screen.height * 0.745, width: screen.width * 0.9, height: 100.0))
textView.text = text
textView.editable = false
textView.selectable = false
textView.textAlignment = NSTextAlignment.Center
textView.font = UIFont.systemFontOfSize(20, weight: 0)
textView.textColor = UIColor.whiteColor()
textView.backgroundColor = UIColor.clearColor()
scroll?.addSubview(textView)
}
}
scroll?.contentSize = CGSizeMake(CGFloat(Int(screen.width) * slides.count), screen.height * 0.5)
scroll?.delegate = self
dots?.addTarget(self, action: Selector("swipe:"), forControlEvents: UIControlEvents.ValueChanged)
let closeButton = UIButton()
closeButton.frame = CGRect(x: screen.width - 70, y: 20, width: 60, height: 60)
closeButton.setTitle("Skip", forState: .Normal)
closeButton.setTitleColor(UIColor(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: 0.5), forState: .Normal)
closeButton.titleLabel!.font = UIFont.systemFontOfSize(16)
closeButton.addTarget(self, action: "pressed:", forControlEvents: .TouchUpInside)
view.addSubview(closeButton)
}
func pressed(sender: UIButton!) {
self.dismissViewControllerAnimated(true) { () -> Void in
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func getFrame (iW: CGFloat, iH: CGFloat, slide: Int, offset: CGFloat) -> CGRect {
let mH: CGFloat = screen.height * 0.50
let mW: CGFloat = screen.width
var h: CGFloat
var w: CGFloat
let r = iW / iH
if (r <= 1) {
h = min(mH, iH)
w = h * r
} else {
w = min(mW, iW)
h = w / r
}
return CGRectMake(
max(0, (mW - w) / 2) + CGFloat(slide) * screen.width,
max(0, (mH - h) / 2) + offset,
w,
h
)
}
func swipe(sender: AnyObject) -> () {
if let scrollView = scroll {
let x = CGFloat(dots!.currentPage) * scrollView.frame.size.width
scroll?.setContentOffset(CGPointMake(x, 0), animated: true)
}
}
func scrollViewDidEndDecelerating(scrollView: UIScrollView) -> () {
let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
dots!.currentPage = Int(pageNumber)
}
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}
}
On your imageView set imageView.contentMode = UIViewContentMode.ScaleAspectFit
Depending on how you want it to scale you should modify the contentMode
of the UIImageView's.
In Objective-C you would do this (it'll be something similar in Swift):
UIImageView * iv = [UIImageView new];
iv.frame = scrollView.bounds;
iv.contentMode = UIViewContentModeScaleAspectFill;
iv.clipsToBounds = true;
iv.image = [UIImage imageNamed:#"image.jpg"];
[scrollView addSubview:iv];
The contentMode is the line you're looking for.

Resources