How to add a Label for Each Image in the iCarousel View Framework - swift

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
}

Related

How to update ScrollView Width after device rotation?

I am following a tutorial to create a swift app that adds a number of views to a scroll view and then allows me to scroll between them. I have the app working and understand it for the most part. When I change the orientation of the device the views width don't get updated so I have parts of more than one view controller on the screen? Does anybody know how to fix this? From my understanding I need to call something in the viewsDidTransition method to redraw the views. Any help would be greatly appreciated. Thanks!
Here is what I have so far:
import UIKit
class ViewController: UIViewController {
private let scrollView = UIScrollView()
private let pageControl: UIPageControl = {
let pageControl = UIPageControl()
pageControl.numberOfPages = 5
pageControl.backgroundColor = .systemBlue
return pageControl
}()
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
pageControl.addTarget(self,
action: #selector(pageControlDidChange(_:)),
for: .valueChanged)
scrollView.backgroundColor = .red
view.addSubview(scrollView)
view.addSubview(pageControl)
}
#objc private func pageControlDidChange(_ sender: UIPageControl){
let current = sender.currentPage
scrollView.setContentOffset(CGPoint(x: CGFloat(current) * view.frame.size.width,
y: 0), animated: true)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
pageControl.frame = CGRect(x: 10, y: view.frame.size.height - 100, width: view.frame.size.width - 20, height: 70)
scrollView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height - 100)
if scrollView.subviews.count == 2 {
configureScrollView()
}
}
private func configureScrollView(){
scrollView.contentSize = CGSize(width: view.frame.size.width*5, height: scrollView.frame.size.height)
scrollView.isPagingEnabled = true
let colors: [UIColor] = [.systemRed, .systemGray, .systemGreen, .systemOrange, .systemPurple]
for x in 0..<5{
let page = UIView(frame: CGRect(x: CGFloat(x) * view.frame.size.width, y: 0, width: view.frame.size.width, height: scrollView.frame.size.height))
page.backgroundColor = colors[x]
scrollView.addSubview(page)
}
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
print("hello world")
}
}
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
pageControl.currentPage = Int(floorf(Float(scrollView.contentOffset.x) / Float(scrollView.frame.size.width)))
}
}

UIScrollView with paging enable not working properly

Trying to add four UIView's in UIScrollView
The issue is next (2, 3, and 4) view gets a bit off from the visible screen view when scroll.
override init(frame: CGRect) {
super.init(frame: frame)
configureSlider()
}
private func configureSlider() {
Bundle.main.loadNibNamed("CarouselSliderView", owner: self, options: nil)
addSubview(contentView)
for i in 0...3 {
let view = UIView()
switch i {
case 0:
view.backgroundColor = .brown
case 1:
view.backgroundColor = .yellow
case 2:
view.backgroundColor = .green
case 3:
view.backgroundColor = .blue
default:
view.backgroundColor = .red
}
slides.append(view)
}
setupSlideScrollView(slides: slides)
pageControl.numberOfPages = slides.count
pageControl.currentPage = 0
self.bringSubviewToFront(pageControl)
}
set each UIView frames:
private func setupSlideScrollView(slides : [UIView]) {
let screenRect = UIScreen.main.bounds
let screenWidth = screenRect.size.width
for i in 0 ..< slides.count {
slides[i].frame = CGRect(x: screenWidth * CGFloat(i), y: 0, width: screenWidth, height: self.frame.height)
topScrollView.addSubview(slides[i])
}
topScrollView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: self.frame.height)
topScrollView.contentSize = CGSize(width: screenWidth * CGFloat(slides.count), height: self.frame.height)
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x/self.frame.width)
pageControl.currentPage = Int(pageIndex)
}

Change label's font size dynamically when scrolling tableView

I have tableView and on top of it an imageView. Made stretchable header with this guide https://github.com/abhimuralidharan/StretchableTableViewHeader-Swift
And now I have to add label on my image. This label should change size/font when tableView is scrolling.
I created my imageView in another class:
class LotteryHeaderView: UIImageView {
let ticketsCountLabel: UILabel = {
let label = UILabel()
label.textColor = .white
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 100)
return label
}()
let infoLabel: UILabel = {
let label = UILabel()
label.textColor = .white
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize: 13, weight: .medium)
label.numberOfLines = 2
label.text = Localizable.all_user_tickets_count()
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubViews([ticketsCountLabel, infoLabel])
ticketsCountLabel.centerX(to: self.centerXAnchor)
.centerY(to: self.centerYAnchor)
infoLabel.top(to: ticketsCountLabel.bottomAnchor, constant: 7)
.width(constant: 184)
.centerX(to: self.centerXAnchor)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Initialized it in my controller:
let imageView = LotteryHeaderView(frame: CGRect(x: 0, y: 0, width: Constants.Size.screenWidth, height: 300))
Setup in viewDidLoad:
imageView.frame = CGRect(x: 0, y: 0, width: Constants.Size.screenWidth, height: 300)
imageView.image = R.image.santa_fe()
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
view.addSubview(imageView)
Here func which gets called every time the tableview is scrolled, and it works for my image (it collapsable and stretchable):
func scrollImageInHeader(scrollView: UIScrollView) {
let y = 300 - (scrollView.contentOffset.y + 300)
let height = min(max(y, 60), 450)
imageView.frame = CGRect(x: 0, y: 0, width: Constants.Size.screenWidth, height: height)
}
Tried to add in scrollImageInHeader() code under, from this StackOverFlowAnswer, but it doesn't help
let offset = scrollView.contentOffset.y
let scale = min(max(1.0 - offset / 200.0, 0.0), 1.0)
imageView.ticketsCountLabel.transform = CGAffineTransform(scaleX: scale, y: scale)
Please, any help will be appreciated.
UIScrollView is parent UITableViewController. You use UIScrollView with UIScrollViewDelegate for setup label font size with scrollOffset: CGFloat follow .y
extension ViewController: UIScrollViewDelegate{
func scrollViewDidScroll(_ scrollView: UIScrollView) {
var scrollOffset : CGFloat = scrollView.contentOffset.y
// process with scrollOffset
}
}
Actually I found my mistake. Code from Here helped.
Class LotteryHeaderView I changed to UIView and added there an UIImageView.

Swift access helper function view

I try to access the function "addNavBar()" from, my helper class, but when I run the emulator, no view is shown on HomeViewController.
Swift 4
HomeViewController.swift
class HomeController: UIViewController {
let NavBar = NavigationBarHelper()
override func viewDidLoad() {
super.viewDidLoad()
NavBar.addNavBar()
}
}
NavigationBarHelper.swift
class NavigationBarHelper: UIView {
func addNavBar() {
let rect = CGRect(x: 10, y: 70, width: 250, height: 100)
let navBarView = UIView(frame: rect)
navBarView.backgroundColor = UIColor.blue
self.addSubview(navBarView)
}
}
self in NavigationBarHelper is not the same object as the view in the view controller. Pass the VC's view as a parameter. There is no need to make NavigationBarHelper a subclass of UIView (in fact it could also be a struct).
class NavigationBarHelper {
func addNavBar(to view: UIView) {
let rect = CGRect(x: 10, y: 70, width: 250, height: 100)
let navBarView = UIView(frame: rect)
navBarView.backgroundColor = UIColor.blue
view.addSubview(navBarView)
}
}
please also stick to naming conventions
class HomeController: UIViewController {
let navBarHelper = NavigationBarHelper()
override func viewDidLoad() {
super.viewDidLoad()
navBarHelper.addNavBar(to: self.view)
}
Instead of creating an object every usage
let NavBar = NavigationBarHelper()
I think it's more robust to make it static like this
class NavigationBarHelper: UIView {
static func addNavBar(view:UIView) {
let rect = CGRect(x: 10, y: 70, width: 250, height: 100)
let navBarView = UIView(frame: rect)
navBarView.backgroundColor = UIColor.blue
view.addSubview(navBarView)
}
}
and call it directly without object creation
NavigationBarHelper.addNavBar(view: self.view)
A Better Alternative for this would be an extension so you don't have to create the special class for this
extension UIView {
func addNavBar() {
let rect = CGRect(x: 10, y: 70, width: 250, height: 100)
let navBarView = UIView(frame: rect)
navBarView.backgroundColor = UIColor.blue
self.addSubview(navBarView)
}
}
And in you UIViewController you can simply write this without creating an object of your helper.
self.view.addNavBar()

Swift Eureka: Form Header Goes underneath NavigationBar

I called a performSegue from a tableView and pushed to a FormVC. However, my header went underneath the navigationBar despite that the UIView is offset 100 pts in the y axis.
My code as follows:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "EventsDetails" {
let destVC = segue.destination as! EventsDetailsViewController
}
}
class EventsDetailsViewController: FormViewController {
override func viewDidLoad() {
super.viewDidLoad()
form +++
Section(){ section in
section.header = {
var header = HeaderFooterView<UIView>(.callback({
let view = UIView(frame: CGRect(x: 0, y: 100, width: 100, height: 180))
let imageView = UIImageView(frame: CGRect(x: 20, y: 10, width: 80, height: 80))
imageView.backgroundColor = .red
imageView.layer.cornerRadius = imageView.frame.size.width / 2
imageView.clipsToBounds = true
let nameLabel = UILabel(frame: CGRect(x: 120, y: 40, width: 150, height: 20))
nameLabel.text = "Test Text"
nameLabel.backgroundColor = .blue
nameLabel.font = UIFont.boldSystemFont(ofSize: 18.0)
view.addSubview(imageView)
view.addSubview(nameLabel)
view.backgroundColor = .white
return view
}))
header.height = { 200 }
return header
}()
}
}
}
Is there a way to move the view down to the bottom of the navBar? By the way I use storyboard. I know this may be a primitive question, but some advice is much appreciated, thanks!