In my viewController which is the delegate of my scrollView
override func viewWillAppear(_ animated: Bool) {
slides = loadSlides()
setupSlideScrollView(slides: slides)
pageControl.numberOfPages = slides.count
pageControl.currentPage = 0
view.bringSubview(toFront: pageControl)
textField.becomeFirstResponder()
}
func loadSlides() -> [Slide] {
let slide1: Slide = Bundle.main.loadNibNamed("Slide", owner: self, options: nil)?.first as! Slide
slide1.quizLabel.text = "This is slide1"
slide1.hintLabel.text = "yeah"
let slide2: Slide = Bundle.main.loadNibNamed("Slide", owner: self, options: nil)?.first as! Slide
slide2.quizLabel.text = "This is slide2"
slide2.hintLabel.text = "YEAH"
let slides = [slide1, slide2]
return slides
}
func setupSlideScrollView(slides : [Slide]) {
let width = view.frame.width
let height = view.frame.height
scrollView.frame = CGRect(x: 0,
y: 0,
width: width,
height: height)
scrollView.contentSize = CGSize(width: CGFloat(slides.count) * width, height: height)
scrollView.isPagingEnabled = true
for slide in slides {
slide.quizLabel.textColor = UIColor.white
slide.quizLabel.font = UIFont(name: (textField.font?.fontName)!, size: 20)
slide.hintLabel.textColor = UIColor.lightGray
slide.hintLabel.font = UIFont(name: (textField.font?.fontName)!, size: 18)
slide.frame = CGRect(x: CGFloat(slides.index(of: slide)!) * width,
y: 0,
width: width,
height: height)
scrollView.addSubview(slide)
}
}
When running, the pageControl shows up with a sliding animation. It seems it slides from the origin of the view. I have no idea why it comes out like that.
The pageControl is at the top
My segue settings as followed
p.s. Also, anyway to solve the similar problem for the sliding labels and the cursor?
I would like to appreciate your help in advance!
Related
I have a UIScrollView in an UIViewController that is presented as Popover. On iPads the contentSize of the ScrollView is not calculated correctly as the view size is always the same as UIScreen.main.bounds.width. As the popover is smaller as the screen the paging fails as each slide is wider than the width of the popover width.
Here is how I load the popover:
let storyboard = UIStoryboard(name: "Onboarding", bundle: nil)
let onboardingVC = storyboard.instantiateViewController(identifier: "Onboarding")
if let popoverController = onboardingVC.popoverPresentationController {
popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2, width: 0, height: 0)
popoverController.sourceView = self.view
popoverController.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
}
present(onboardingVC, animated: true, completion: nil)
And this is how I calculate the contentSize in the OnboardingViewController:
func setupSlideScrollView(slides : [Slide]) {
scrollView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
scrollView.contentSize = CGSize(width: view.frame.width * CGFloat(slides.count), height: 1.0)
scrollView.isPagingEnabled = true
for i in 0 ..< slides.count {
slides[i].frame = CGRect(x: view.frame.width * CGFloat(i), y: 0, width: view.frame.width, height: view.frame.height)
scrollView.addSubview(slides[i])
}
}
SOLUTION:
I think I found the solution myself. I had to call func setupSlideScrollView in override func viewWillLayoutSubviews() and not in override func viewDidLoad().
I have used the iCarousel Framework in my View Controller. But, I am not sure how can I add a label below each image while scrolling in the carousel view. Would appreciate your help! Thanks!
func numberOfItems(in carousel: iCarousel) -> Int {
return 10
}
func carousel(_ carousel: iCarousel, viewForItemAt index: Int, reusing view: UIView?) -> UIView {
let view = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width/1.4, height: 300))
view.backgroundColor = .red
let imageview = UIImageView(frame: view.bounds)
view.addSubview(imageview)
imageview.contentMode = .scaleToFill
imageview.image = UIImage(named: "Dog_\(index+1)")
return view
}
func carouselDidEndScrollingAnimation() {
if (myCarousel.currentItemIndex == 1) {
dogNameLabel.text = "Brownie!"
}
}
let myCarousel: iCarousel = {
let view = iCarousel()
view.type = .rotary
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(myCarousel)
myCarousel.dataSource = self
myCarousel.frame = CGRect(x: 0, y: 220, width: view.frame.size.width, height: 400)
}
There are too many option. You can create custom view (xib) for reusability. You need to label in contentView above imageView.
But you need to create view like that.
func carousel(_ carousel: iCarousel, viewForItemAt index: Int, reusing view: UIView?) -> UIView {
let view = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width/1.4, height: 300))
view.backgroundColor = .red
let imageview = UIImageView(frame: view.bounds)
view.addSubview(imageview)
imageview.contentMode = .scaleToFill
imageview.image = UIImage(named: "Dog_\(index+1)")
let label = UILabel()
label.text = "Enter your text"
label.frame = CGRect(x: 0, y: 20, width: view.frame.size.width, height: 30)
//or use constraints
view.addSubview(label)
return view
}
I have a UIScrollView. I have a UITextField and a UILabel. For some reason my UITextField it will not move in my scroll view but my UILablel will. I have added the UITextField the same way as I added my UILabel to the scrollview using scrollView.addSubview(textField). Anyone see what I am doing wrong on this one?
import Foundation
import UIKit
//here
protocol AddContactDelegate {
func addContact(contact: Contact)
}
class AddContactController: UIViewController {
//delegate
var delegate: AddContactDelegate?
//TextField
let textField: UITextField = {
let tf = UITextField()
tf.placeholder = "Add Your Workout Title"
tf.textAlignment = .center
tf.translatesAutoresizingMaskIntoConstraints = false
return tf
}()
override func viewDidLoad() {
super.viewDidLoad()
//making scroll view
let screensize: CGRect = UIScreen.main.bounds
let screenWidth = screensize.width
let screenHeight = screensize.height
var scrollView: UIScrollView!
scrollView = UIScrollView(frame: CGRect(x: 0, y: 120, width: screenWidth, height: screenHeight))
scrollView.contentSize = CGSize(width: screenWidth, height: 2000)
view.addSubview(scrollView)
//setting up how view looks-----
view.backgroundColor = .white
//top buttons
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleDone))
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(handleCancel))
//view elements
view.addSubview(textField)
scrollView.addSubview(textField)
textField.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
textField.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
textField.widthAnchor.constraint(equalToConstant: view.frame.width - 64).isActive = true
textField.becomeFirstResponder()
//excercise label
let excerciseNumber = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
excerciseNumber.center = CGPoint(x: view.frame.width / 2 , y: view.frame.height / 20)
excerciseNumber.textAlignment = .center
excerciseNumber.text = "Workout Title"
self.view.addSubview(excerciseNumber)
scrollView.addSubview(excerciseNumber)
}
//done button
#objc func handleDone(){
print("done")
guard let fullname = textField.text, textField.hasText else {
print("handle error here")
return
}
let contact = Contact(fullname: fullname, hello: "hi")
delegate?.addContact(contact: contact)
print(contact.fullname)
print(contact.hello)
}
//cancel button
#objc func handleCancel(){
self.dismiss(animated: true, completion: nil )
}
}
As you make the center x and y of the textfield with view not scrollView , You need
textField.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
textField.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
textField.centerYAnchor.constraint(equalTo: scrollView.centerYAnchor),
textField.widthAnchor.constraint(equalToConstant: view.frame.width - 64)
])
Also remove
view.addSubview(textField)
self.view.addSubview(excerciseNumber)
I have managed to create, a dark overlay once clicked a search icon and have managed to add a table uiview on the dark overlay but now want to add a search bar within that table view. I cant seem to figure it out as my code seems different to everyone else's examples. I am new to swift so my code probably isn't the cleanest. can i ask if someone can show me how to do this as i am out of ideas. I have posted my code below can someone please show me where i'm going wrong.
Many thanks
class SearchLauncher: NSObject {
let blackView = UIView()
let tableView = UITableView()
#objc func showSearch() {
if let window = UIApplication.shared.keyWindow {
blackView.backgroundColor = UIColor(white: 0, alpha: 0.5)
blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleDismiss)))
window.addSubview(blackView)
window.addSubview(tableView)
let height: CGFloat = 600
let y = window.frame.height - height
tableView.frame = CGRect(x: 0, y: window.frame.height, width: window.frame.width, height: height)
blackView.frame = window.frame
blackView.alpha = 0
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.blackView.alpha = 1
self.tableView.frame = CGRect(x: 0, y: y, width: self.tableView.frame.width, height: self.tableView.frame.height)
}, completion: nil)
}
}
#objc func handleDismiss() {
UIView.animate(withDuration: 0.5) {
self.blackView.alpha = 0
if let window = UIApplication.shared.keyWindow {
self.tableView.frame = CGRect(x: 0, y: window.frame.height, width: self.tableView.frame.width, height: self.tableView.frame.height)
}
}
}
override init() {
super.init()
//start doing something here maybe
}
}```
How did you try to add a search controller?
I would do it by adding an UISearchController as a tableHeaderView of your table view. First make sure to add UISearchResultsUpdating protocol to your class.
class SearchLauncher: NSObject, UISearchResultsUpdating
Then add the search bar to your table view
let searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.sizeToFit()
searchController.searchResultsUpdater = self
//you probably don't need this
//searchController.dimsBackgroundDuringPresentation = false
tableView.tableHeaderView = searchController.searchBar
And then, implement the updateSearchResults(for:_) delegate method
func updateSearchResults(for searchController: UISearchController) {
filteredTableData.removeAll(keepingCapacity: false)
//filter the table data by using searchController.searchBar.text!
//filteredTableData = ...
self.tableView.reloadData()
}
I am creating an animation which brings an image and a label from the left to the centre of the view.
imageLogo.isHidden = true is not hidden when App is run
labelLogo is not shown at all on the view
I have been reading tutorials, but I just don't see what is wrong with my code.
let paymentLogo = UIImage(named: "paymentImage")
var imageLogo:UIImageView!
var overlayView = UIView()
var logoAppeared:Bool!
let labelLogo = UILabel()
override func viewDidLayoutSubviews() {
//move picture off the screen here
self.imageLogo = UIImageView(image:paymentLogo)
imageLogo.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
imageLogo.center.x -= 400
self.view.addSubview(imageLogo)
self.labelLogo.frame =
CGRect(x: 0, y: 0, width: 200, height: 21)
self.labelLogo.center.x -= 400
self.labelLogo.text = "Booking Completed"
self.labelLogo.textAlignment = .center
self.view.addSubview(labelLogo)
}
override func viewDidAppear(_ animated: Bool) {
UIView.animate(withDuration: 2.0, delay: 0.1, options: [], animations: {
//animate paymentCompletedLogo
self.overlayView = UIView(frame: self.view.frame)
self.overlayView.backgroundColor = UIColor.black
self.overlayView.alpha = 0.4
//animate labelLogo
self.labelLogo.frame = CGRect(x: self.view.center.x, y: 90, width: 200, height: 21)
self.labelLogo.backgroundColor = UIColor.gray
self.labelLogo.text = "Booking Completed"
self.labelLogo.textColor = .black
self.labelLogo.textAlignment = .center
//animate imageLogo
self.imageLogo.frame =
CGRect(x: self.view.center.x,y: self.view.center.y,width: 100,height: 100)
self.view.addSubview(self.overlayView)
self.view.addSubview(self.imageLogo)
self.view.addSubview(self.labelLogo)
}) { finished in
self.overlayView.isHidden = true
self.imageLogo.isHidden = true //it is not hidden in simulator
self.logoAppeared = true
}
}
I tried removing following your code from animation method it worked fine.
You are trying to add subview in animation method. imageLogo and labelLogo is all ready added in view.
self.view.addSubview(self.overlayView)
self.view.addSubview(self.imageLogo)
self.view.addSubview(self.labelLogo)