How can I change items in tabBar? - ios

I created a custom bar but I can't change the location of the image and text in the itembar itself.
What I have:
and here is what I want to get:
How I initialize barItems:
private func initializeTabBar() {
let mainNavigationController = MainNavigationController()
mainNavigationController.tabBarItem = UITabBarItem(title: "Explorer", image: UIImage(named: "dot"), tag: 0)
let mainCoordinator = coordinatorFactory.makeMainCoordinator(with: Router(rootController: mainNavigationController))
let BasketViewController = BusketViewController()
BasketViewController.tabBarItem = UITabBarItem(title: "", image: UIImage(named: "busket"), tag: 1)
let FavoriteViewController = FavoriteViewController()
FavoriteViewController.tabBarItem = UITabBarItem(title: "", image: UIImage(named: "heart"), tag: 2)
let ProfileViewController = ProfileViewController()
ProfileViewController.tabBarItem = UITabBarItem(title: "", image: UIImage(named: "profile"), tag: 3)
tabBarController.viewControllers = [mainNavigationController,BasketViewController,FavoriteViewController,ProfileViewController]
tabbar setup:
func setup() {
tabBar.itemWidth = tabBar.bounds.width / 10
tabBar.itemPositioning = .centered
tabBar.tintColor = AppColors.white
tabBar.unselectedItemTintColor = AppColors.white
}
func setupBackground() {
let positionX: CGFloat = 0
let PositionY: CGFloat = 8
let width = tabBar.bounds.width - positionX * 2
let height = tabBar.bounds.height + PositionY * 2
let rounderLayer = CAShapeLayer()
let bezierPath = UIBezierPath(
roundedRect: CGRect(x: positionX, y: tabBar.bounds.minY - PositionY, width: width, height: height), cornerRadius: height / 2 )
rounderLayer.path = bezierPath.cgPath
rounderLayer.fillColor = AppColors.darkBlue.cgColor
tabBar.layer.insertSublayer(rounderLayer, at: 0)
}
I will accept all advice or solutions.

Related

TextClassification/ Extraction from image How to get single text frame and string Using Core ML from a Image

Need to mark the rec boxes around string and then to get that string after tapping
import UIKit
import Vision
class ViewController: UIViewController, ImageGet {
//MARK: OUTLETS
#IBOutlet weak var selectButton: UIButton!
//MARK: VARIABLES
var objU = UtilityClass()
var image:UIImage?
var str:String?
var uiButton : UIButton?
var arrayString = [String]()
var imageView : UIImageView = UIImageView()
//MARK: DELEGATE FUNCTION
func img(image: UIImage) {
self.image = image
imageView.image = image
setUp()
}
override func viewDidLoad() {
super.viewDidLoad()
imageView.isUserInteractionEnabled = true
// Do any additional setup after loading the view.
}
//MARK: SETUPUI
func setUp() {
let realImg = resizeImage(image: (imageView.image!) , targetSize:CGSize(width: view.frame.width, height: view.frame.height) )
self.image = realImg
self.imageView .image = self.image
imageView.isUserInteractionEnabled = true
self.imageView.frame = CGRect(x: 0, y: 0, width: realImg.size.width, height: realImg.size.height)
view.addSubview(imageView)
guard let cgimg = realImg.cgImage else {return}
let requestHandler = VNImageRequestHandler(cgImage: cgimg)
let req = VNRecognizeTextRequest(completionHandler: recognizeTextHandler)
req.recognitionLevel = .accurate
do {
try requestHandler.perform([req])
} catch {
print("Unable to perform the request: \(error)")
}
}
//MARK: SELECT THE IMAGE
#IBAction func selectButtontapped(_ sender: Any) {
objU.delegate = self
objU.obj = self
objU.ImageGet()
}
func recognizeTextHandler(request : VNRequest , error:Error?) {
guard let observation = request.results as? [VNRecognizedTextObservation], error == nil else {
return
}
_ = observation.compactMap({
$0.topCandidates(1).first?.string
}).joined(separator: "/n")
for subView in imageView.subviews {
subView.removeFromSuperview()
}
let boundingRect :[CGRect] = observation.compactMap{
observation in
guard let candidate = observation.topCandidates(1).first else {return .zero}
//find the bounding box observation
let stringRange = candidate.string.startIndex..<candidate.string.endIndex
let boxObservation = try? candidate.boundingBox(for: stringRange)
let boundingBox = boxObservation?.boundingBox ?? .zero
str = candidate.string
self.arrayString.append(str!)
let rectInImg = VNImageRectForNormalizedRect(boundingBox, Int((imageView.frame.size.width)), Int((imageView.frame.size.height)))
let convertedRect = self.getConvertedRect(boundingBox: observation.boundingBox, inImage:image!.size , containedIn: (imageView.bounds.size))
drawBoundBox(rect: convertedRect)
return rectInImg
}
print(arrayString)
print(boundingRect)
}
func drawBoundBox(rect: CGRect) {
uiButton = UIButton(type: .custom)
uiButton?.frame = rect
uiButton?.layer.borderColor = UIColor.systemPink.cgColor
uiButton?.setTitle("", for: .normal)
uiButton?.layer.borderWidth = 2
uiButton?.tag = arrayString.count
imageView.addSubview(uiButton ?? UIButton())
uiButton?.addTarget(self, action: #selector(pressed(_:)), for: .touchUpInside)
}
#objc func pressed(_ sender : UIButton) {
alert(key: arrayString[sender.tag - 1])
}
//MARK: CONVERT THE NORMALISED BOUNDING RECT
func getConvertedRect(boundingBox: CGRect, inImage imageSize: CGSize, containedIn containerSize: CGSize) -> CGRect {
let rectOfImage: CGRect
let imageAspect = imageSize.width / imageSize.height
let containerAspect = containerSize.width / containerSize.height
if imageAspect > containerAspect { /// image extends left and right
let newImageWidth = containerSize.height * imageAspect /// the width of the overflowing image
let newX = -(newImageWidth - containerSize.width) / 2
rectOfImage = CGRect(x: newX, y: 0, width: newImageWidth, height: containerSize.height)
} else { /// image extends top and bottom
let newImageHeight = containerSize.width * (1 / imageAspect) /// the width of the overflowing image
let newY = -(newImageHeight - containerSize.height) / 2
rectOfImage = CGRect(x: 0, y: newY, width: containerSize.width, height: newImageHeight)
}
let newOriginBoundingBox = CGRect(
x: boundingBox.origin.x,
y: 1 - boundingBox.origin.y - boundingBox.height,
width: boundingBox.width,
height: boundingBox.height
)
var convertedRect = VNImageRectForNormalizedRect(newOriginBoundingBox, Int(rectOfImage.width), Int(rectOfImage.height))
/// add the margins
convertedRect.origin.x += rectOfImage.origin.x
convertedRect.origin.y += rectOfImage.origin.y
return convertedRect
}
//MARK: RESIZE THE IMAGE ACCORD TO DEVICE
func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage {
let size = image.size
let widthRatio = targetSize.width / image.size.width
let heightRatio = targetSize.height / image.size.height
// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
if(widthRatio > heightRatio) {
newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
} else {
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
}
// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
// Actually do the resizing to the rect using the ImageContext stuff
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
//MARK: POPPING ALERT WITH STRING
func alert(key:String){
let alertController = UIAlertController(title: "String", message: key, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default) {
(action: UIAlertAction!) in
// Code in this block will trigger when OK button tapped.
}
let copyAction = UIAlertAction(title: "Copy", style: .default) {
(action: UIAlertAction!) in
UIPasteboard.general.string = key
}
alertController.addAction(copyAction)
alertController.addAction(OKAction)
self.present(alertController, animated: true, completion: nil)
}
}

Trying to display an image from the asset folder

Im trying to display an image titled 'purpleConfetti' from my assets folder in my code, but I receive an error, 'use of unresolved identifier'. How do I fix this?
func displayConfetti() {
let emitter = Emitter.get(with: purpleConfetti)
emitter.emitterPosition = CGPoint(x: view.frame.size.width / 2, y: -10)
emitter.emitterSize = CGSize(width: view.frame.size.width, height: 2)
view.layer.addSublayer(emitter)
}
the goal of the entire project is to have confetti fall from the top of the interface.
import UIKit
class Emitter {
static func get(with image: UIImage) -> CAEmitterLayer {
let emitter = CAEmitterLayer()
emitter.emitterShape = CAEmitterLayerEmitterShape.line
emitter.emitterCells = generateEmitterCells(with: image)
return emitter
}
static func generateEmitterCells(with image: UIImage) -> [CAEmitterCell] {
var cells = [CAEmitterCell]()
let cell = CAEmitterCell()
cell.contents = image.cgImage
cell.birthRate = 4
cell.lifetime = 14
cell.velocity = CGFloat(25)
cell.emissionLongitude = (180 * (.pi/180))
cell.emissionRange = (45 * (.pi/180))
cell.spinRange = 3.5
cell.scale = 0.1
cell.scaleRange = 0.25
cells.append(cell)
return cells
}
}
You need to load your image:
let purpleConfetti: UIImage = UIImage(named: "purpleConfetti")
let emitter: Emitter = Emitter.get(with: purpleConfetti)
Replace let emitter = Emitter.get(with: purpleConfetti) with
let emitter = Emitter.get(with: UIImage(named: "purpleConfetti"))
OR
let emitter = Emitter.get(with: #imageLiteral(resourceName: "purpleConfetti"))

Horizontal ScrollView not fit its sub ImageViews?

I want horizontal scrollview with image view but image is not fitting with the scroll. i am doing this code but not getting the right thing
Here is my code
#IBOutlet weak var upperScroll: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.isHidden = true
// Do any additional setup after loading the view.
var logoImage: [UIImage] = [
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
]
upperScroll.isScrollEnabled = true
let scrollWidth: Int = Int(self.view.frame.width)
upperScroll.contentSize = CGSize(width: CGFloat(scrollWidth), height:(self.upperScroll.frame.height))
upperScroll.frame = CGRect(x: 0, y: 51, width: upperScroll.frame.size.width, height: self.upperScroll.frame.height)
upperScroll.backgroundColor = UIColor.red
var xOffset: Int = 0
for index in 0..<logoImage.count {
let img = UIImageView(frame: CGRect(x: CGFloat(xOffset), y: 0, width: upperScroll.frame.size.width, height: self.upperScroll.frame.height))
img.image = logoImage[index]
upperScroll.addSubview(img)
xOffset += 100
}
view.addSubview(upperScroll)
upperScroll.contentSize = CGSize(width: CGFloat((scrollWidth + xOffset)), height: 110)
}
but i want this
Can anyone please help me? Thanks
Just remove your appdelegate code and add my fuction
also set scrollview constraint like leading,trailing,top,bottom Zero
func scrollImage() {
super.viewDidLoad()
self.navigationController?.navigationBar.isHidden = true
// Do any additional setup after loading the view.
var logoImage: [UIImage] = [
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!]
upperScroll.isPagingEnabled = true
upperScroll.isScrollEnabled = true
let scrollWidth: Int = Int(self.view.frame.width)
,
upperScroll.contentSize = CGSize(width: CGFloat(scrollWidth), height:(self.upperScroll.frame.height))
print(upperScroll.frame.size.width)
upperScroll.backgroundColor = UIColor.red
for index in 0..<logoImage.count {
let xPosition = self.view.frame.width * CGFloat(index)
upperScroll.layoutIfNeeded()
let img = UIImageView(frame: CGRect(x: CGFloat(xPosition), y: 0, width: upperScroll.frame.size.width, height: self.upperScroll.frame.height))
img.layoutIfNeeded()
img.image = logoImage[index]
upperScroll.addSubview(img)
}
view.addSubview(upperScroll)
upperScroll.contentSize = CGSize(width: CGFloat((scrollWidth) * logoImage.count), height: self.upperScroll.frame.height)
}
I hope it's save your time and working great
According to your requirement, the xOffset += 100 should be changed to xOffset += scrollWidth. And contents size set to:
upperScroll.contentSize = CGSize(width: CGFloat((scrollWidth * logoImage.count)), height: 110)
And remember to enable the pagination for scroll view.
First of all, you need two outlet for scroll view and PageControl,
var contentWidth:CGFloat = 0.0
// MARK: - Welcome screen with scroll view use page controll
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
scrollView.delegate = self
let myImages = ["intro1_1.png", "intro2_2.png", "intro3_3.png"] // images which loaded in assets
let imageWidth:CGFloat = view.frame.width
let imageHeight:CGFloat = view.frame.height
var xPosition:CGFloat = 0 //setup your position
var scrollViewSize:CGFloat=0 //setup your position
for image in myImages {
let myImage:UIImage = UIImage(named: image)!
let myImageView:UIImageView = UIImageView()
myImageView.image = myImage
myImageView.frame.size.width = imageWidth
myImageView.frame.size.height = imageHeight
myImageView.frame.origin.x = xPosition
myImageView.frame.origin.y = 0
scrollView.addSubview(myImageView)
xPosition += imageWidth
scrollViewSize += imageWidth
}
scrollView.contentSize = CGSize(width: scrollViewSize, height: imageHeight)
scrollView.contentSize = CGSize(width: view.frame.width * 3, height: view.frame.height) //here you setup how many pages in scroll will
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageWidth:CGFloat = scrollView.frame.width
let currentPage:CGFloat = floor((scrollView.contentOffset.x-pageWidth / 2)/pageWidth)+1
self.pageControll.currentPage = Int(currentPage)
}
hope, i help u

SwiftPages updateUI Does Not Work with Swift 3

I'm using Swiftpages. When app is opened it looks like first picture.
But app goes to background and opened different app on device, after open again my app it looks like second picture.
I updated to Swift 3, but I can't figure out the issue, I write about it on Github but no reply from them.
public class SwiftPages: UIView {
private lazy var token = 0
var containerVieww: UIView!
private var scrollView: UIScrollView!
private var topBar: UIView!
var animatedBar: UIView!
var viewControllerIDs = [String]()
private var buttonTitles = [String]()
private var buttonImages = [UIImage]()
private var pageViews = [UIViewController?]()
private var currentPage: Int = 0
// Container view position variables
private var xOrigin: CGFloat = 0
private var yOrigin: CGFloat = 64
private var distanceToBottom: CGFloat = 0
// Color variables
private var animatedBarColor = UIColor(red: 28/255, green: 95/255, blue: 185/255, alpha: 1)
private var topBarBackground = UIColor.white
private var buttonsTextColor = UIColor.gray
private var containerViewBackground = UIColor.white
// Item size variables
private var topBarHeight: CGFloat = 52
private var animatedBarHeight: CGFloat = 3
// Bar item variables
private var aeroEffectInTopBar = false //This gives the top bap a blurred effect, also overlayes the it over the VC's
private var buttonsWithImages = false
var barShadow = true
private var shadowView : UIView!
private var shadowViewGradient = CAGradientLayer()
private var buttonsTextFontAndSize = UIFont(name: "HelveticaNeue-Light", size: 20)!
private var blurView : UIVisualEffectView!
private var barButtons = [UIButton?]()
// MARK: - Positions Of The Container View API -
public func setOriginX (origin : CGFloat) { xOrigin = origin }
public func setOriginY (origin : CGFloat) { yOrigin = origin }
public func setDistanceToBottom (distance : CGFloat) { distanceToBottom = distance }
// MARK: - API's -
public func setAnimatedBarColor (color : UIColor) { animatedBarColor = color }
public func setTopBarBackground (color : UIColor) { topBarBackground = color }
public func setButtonsTextColor (color : UIColor) { buttonsTextColor = color }
public func setContainerViewBackground (color : UIColor) { containerViewBackground = color }
public func setTopBarHeight (pointSize : CGFloat) { topBarHeight = pointSize}
public func setAnimatedBarHeight (pointSize : CGFloat) { animatedBarHeight = pointSize}
public func setButtonsTextFontAndSize (fontAndSize : UIFont) { buttonsTextFontAndSize = fontAndSize}
public func enableAeroEffectInTopBar (boolValue : Bool) { aeroEffectInTopBar = boolValue}
public func enableButtonsWithImages (boolValue : Bool) { buttonsWithImages = boolValue}
public func enableBarShadow (boolValue : Bool) { barShadow = boolValue}
override public func draw(_ rect: CGRect) {
DispatchQueue.main.async {
let pagesContainerHeight = self.frame.height - self.yOrigin - self.distanceToBottom
let pagesContainerWidth = self.frame.width
// Set the notifications for an orientation change & BG mode
let defaultNotificationCenter = NotificationCenter.default
defaultNotificationCenter.addObserver(self, selector: #selector(SwiftPages.applicationWillEnterBackground), name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
defaultNotificationCenter.addObserver(self, selector: #selector(SwiftPages.orientationWillChange), name: NSNotification.Name.UIApplicationWillChangeStatusBarOrientation, object: nil)
defaultNotificationCenter.addObserver(self, selector: #selector(SwiftPages.orientationDidChange), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
defaultNotificationCenter.addObserver(self, selector: #selector(SwiftPages.applicationWillEnterForeground), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
// Set the containerView, every item is constructed relative to this view
self.containerVieww = UIView(frame: CGRect(x: self.xOrigin, y: self.yOrigin, width: pagesContainerWidth, height: pagesContainerHeight))
self.containerVieww.backgroundColor = self.containerViewBackground
self.containerVieww.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(self.containerVieww)
//Add the constraints to the containerView.
if #available(iOS 9.0, *) {
let horizontalConstraint = self.containerVieww.centerXAnchor.constraint(equalTo: self.centerXAnchor)
let verticalConstraint = self.containerVieww.centerYAnchor.constraint(equalTo: self.centerYAnchor)
let widthConstraint = self.containerVieww.widthAnchor.constraint(equalTo: self.widthAnchor)
let heightConstraint = self.containerVieww.heightAnchor.constraint(equalTo: self.heightAnchor)
NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}
// Set the scrollview
if self.aeroEffectInTopBar {
self.scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: self.containerVieww.frame.size.width, height: self.containerVieww.frame.size.height))
} else {
self.scrollView = UIScrollView(frame: CGRect(x: 0, y: self.topBarHeight, width: self.containerVieww.frame.size.width, height: self.containerVieww.frame.size.height - self.topBarHeight))
}
self.scrollView.isPagingEnabled = true
self.scrollView.showsHorizontalScrollIndicator = false
self.scrollView.showsVerticalScrollIndicator = false
self.scrollView.delegate = self
self.scrollView.backgroundColor = UIColor.clear
self.scrollView.contentOffset = CGPoint(x: 0, y: 0)
self.scrollView.translatesAutoresizingMaskIntoConstraints = false
self.scrollView.isScrollEnabled = false
self.containerVieww.addSubview(self.scrollView)
// Add the constraints to the scrollview.
if #available(iOS 9.0, *) {
let leadingConstraint = self.scrollView.leadingAnchor.constraint(equalTo: self.containerVieww.leadingAnchor)
let trailingConstraint = self.scrollView.trailingAnchor.constraint(equalTo: self.containerVieww.trailingAnchor)
let topConstraint = self.scrollView.topAnchor.constraint(equalTo: self.containerVieww.topAnchor)
let bottomConstraint = self.scrollView.bottomAnchor.constraint(equalTo: self.containerVieww.bottomAnchor)
NSLayoutConstraint.activate([leadingConstraint, trailingConstraint, topConstraint, bottomConstraint])
}
// Set the top bar
self.topBar = UIView(frame: CGRect(x: 0, y: 0, width: self.containerVieww.frame.size.width, height: self.topBarHeight))
self.topBar.backgroundColor = self.topBarBackground
if self.aeroEffectInTopBar {
// Create the blurred visual effect
// You can choose between ExtraLight, Light and Dark
self.topBar.backgroundColor = UIColor.clear
let blurEffect: UIBlurEffect = UIBlurEffect(style: .light)
self.blurView = UIVisualEffectView(effect: blurEffect)
self.blurView.frame = self.topBar.bounds
self.blurView.translatesAutoresizingMaskIntoConstraints = false
self.topBar.addSubview(self.blurView)
}
self.topBar.translatesAutoresizingMaskIntoConstraints = false
self.containerVieww.addSubview(self.topBar)
// Set the top bar buttons
// Check to see if the top bar will be created with images ot text
if self.buttonsWithImages {
var buttonsXPosition: CGFloat = 0
for (index, image) in self.buttonImages.enumerated() {
let frame = CGRect(x: buttonsXPosition, y: 0, width: self.containerVieww.frame.size.width / CGFloat(self.viewControllerIDs.count), height: self.topBarHeight)
let barButton = UIButton(frame: frame)
barButton.backgroundColor = UIColor.clear
barButton.imageView?.contentMode = .scaleAspectFit
barButton.setImage(image, for: .normal)
barButton.tag = index
barButton.addTarget(self, action: #selector(SwiftPages.barButtonAction), for: .touchUpInside)
self.topBar.addSubview(barButton)
self.barButtons.append(barButton)
buttonsXPosition += self.containerVieww.frame.size.width / CGFloat(self.viewControllerIDs.count)
}
} else {
var buttonsXPosition: CGFloat = 0
for (index, title) in self.buttonTitles.enumerated() {
let frame = CGRect(x: buttonsXPosition, y: 0, width: self.containerVieww.frame.size.width / CGFloat(self.viewControllerIDs.count), height: self.topBarHeight)
let barButton = UIButton(frame: frame)
barButton.backgroundColor = UIColor.clear
barButton.titleLabel!.font = self.buttonsTextFontAndSize
barButton.setTitle(title, for: .normal)
barButton.setTitleColor(self.buttonsTextColor, for: .normal)
barButton.tag = index
barButton.addTarget(self, action: #selector(SwiftPages.barButtonAction), for: .touchUpInside)
self.topBar.addSubview(barButton)
self.barButtons.append(barButton)
buttonsXPosition += self.containerVieww.frame.size.width / CGFloat(self.viewControllerIDs.count)
}
}
// Set up the animated UIView
self.animatedBar = UIView(frame: CGRect(x: 0, y: self.topBarHeight - self.animatedBarHeight + 1, width: (self.containerVieww.frame.size.width / CGFloat(self.viewControllerIDs.count)) * 0.8, height: self.animatedBarHeight))
self.animatedBar.center.x = self.containerVieww.frame.size.width / CGFloat(self.viewControllerIDs.count << 1)
self.animatedBar.backgroundColor = self.animatedBarColor
self.containerVieww.addSubview(self.animatedBar)
// Add the bar shadow (set to true or false with the barShadow var)
if self.barShadow {
self.shadowView = UIView(frame: CGRect(x: 0, y: self.topBarHeight, width: self.containerVieww.frame.size.width, height: 4))
self.shadowViewGradient.frame = self.shadowView.bounds
self.shadowViewGradient.colors = [UIColor(red: 150/255, green: 150/255, blue: 150/255, alpha: 0.28).cgColor, UIColor.clear.cgColor]
self.shadowView.layer.insertSublayer(self.shadowViewGradient, at: 0)
self.containerVieww.addSubview(self.shadowView)
}
let pageCount = self.viewControllerIDs.count
// Fill the array containing the VC instances with nil objects as placeholders
for _ in 0..<pageCount {
self.pageViews.append(nil)
}
// Defining the content size of the scrollview
let pagesScrollViewSize = self.scrollView.frame.size
self.scrollView.contentSize = CGSize(width: pagesScrollViewSize.width * CGFloat(pageCount), height: pagesScrollViewSize.height)
// Load the pages to show initially
self.loadVisiblePages()
// Do the initial alignment of the subViews
self.alignSubviews()
}
}
// MARK: - Initialization Functions -
public func initializeWithVCIDsArrayAndButtonTitlesArray (VCIDsArray: [String], buttonTitlesArray: [String]) {
// Important - Titles Array must Have The Same Number Of Items As The viewControllerIDs Array
if VCIDsArray.count == buttonTitlesArray.count {
viewControllerIDs = VCIDsArray
buttonTitles = buttonTitlesArray
buttonsWithImages = false
} else {
print("Initilization failed, the VC ID array count does not match the button titles array count.")
}
}
public func initializeWithVCIDsArrayAndButtonImagesArray (VCIDsArray: [String], buttonImagesArray: [UIImage]) {
// Important - Images Array must Have The Same Number Of Items As The viewControllerIDs Array
if VCIDsArray.count == buttonImagesArray.count {
viewControllerIDs = VCIDsArray
buttonImages = buttonImagesArray
buttonsWithImages = true
} else {
print("Initilization failed, the VC ID array count does not match the button images array count.")
}
}
public func loadPage(page: Int) {
// If it's outside the range of what you have to display, then do nothing
guard page >= 0 && page < viewControllerIDs.count else { return }
// Do nothing if the view is already loaded.
guard pageViews[page] == nil else { return }
print("Loading Page \(page)")
// The pageView instance is nil, create the page
var frame = scrollView.bounds
frame.origin.x = frame.size.width * CGFloat(page)
frame.origin.y = 0.0
// Look for the VC by its identifier in the storyboard and add it to the scrollview
let newPageView = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: viewControllerIDs[page])
newPageView.view.frame = frame
scrollView.addSubview(newPageView.view)
// Replace the nil in the pageViews array with the VC just created
pageViews[page] = newPageView
}
public func loadVisiblePages() {
// First, determine which page is currently visible
let pageWidth = scrollView.frame.size.width
let page = Int(floor((scrollView.contentOffset.x * 2.0 + pageWidth) / (pageWidth * 2.0)))
// Work out which pages you want to load
let firstPage = page - 1
let lastPage = page + 1
// Load pages in our range
for index in firstPage...lastPage {
loadPage(page: index)
}
}
public func barButtonAction(sender: UIButton?) {
let index = sender!.tag
let pagesScrollViewSize = scrollView.frame.size
scrollView.setContentOffset(CGPoint(x: pagesScrollViewSize.width * CGFloat(index), y: 0), animated: true)
currentPage = index
}
// MARK: - Orientation Handling Functions -
public func alignSubviews() {
let pageCount = viewControllerIDs.count
// Setup the new frames
scrollView.contentSize = CGSize(width: CGFloat(pageCount) * scrollView.bounds.size.width, height: scrollView.bounds.size.height)
topBar.frame = CGRect(x: 0, y: 0, width: containerVieww.frame.size.width, height: topBarHeight)
blurView?.frame = topBar.bounds
animatedBar.frame.size = CGSize(width: (containerVieww.frame.size.width / (CGFloat)(viewControllerIDs.count)) * 0.8, height: animatedBarHeight)
if barShadow {
shadowView.frame.size = CGSize(width: containerVieww.frame.size.width, height: 4)
shadowViewGradient.frame = shadowView.bounds
}
// Set the new frame of the scrollview contents
for (index, controller) in pageViews.enumerated() {
controller?.view.frame = CGRect(x: CGFloat(index) * scrollView.bounds.size.width, y: 0, width: scrollView.bounds.size.width, height: scrollView.bounds.size.height)
}
// Set the new frame for the top bar buttons
var buttonsXPosition: CGFloat = 0
for button in barButtons {
button?.frame = CGRect(x: buttonsXPosition, y: 0, width: containerVieww.frame.size.width / CGFloat(viewControllerIDs.count), height: topBarHeight)
buttonsXPosition += containerVieww.frame.size.width / CGFloat(viewControllerIDs.count)
}
}
func applicationWillEnterBackground() {
//Save the current page
currentPage = Int(scrollView.contentOffset.x / scrollView.bounds.size.width)
print("Haydar")
}
func orientationWillChange() {
//Save the current page
currentPage = Int(scrollView.contentOffset.x / scrollView.bounds.size.width)
}
func orientationDidChange() {
//Update the view
alignSubviews()
scrollView.contentOffset = CGPoint(x: CGFloat(currentPage) * scrollView.frame.size.width, y: 0)
}
func applicationWillEnterForeground() {
alignSubviews()
scrollView.contentOffset = CGPoint(x: CGFloat(currentPage) * scrollView.frame.size.width, y: 0)
initializeWithVCIDsArrayAndButtonTitlesArray(VCIDsArray: buttonTitles, buttonTitlesArray: buttonTitles)
print("ForegroundHound")
}
public func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
let previousPage : NSInteger = currentPage
let pageWidth : CGFloat = scrollView.frame.size.width
let fractionalPage = scrollView.contentOffset.x / pageWidth
let page : NSInteger = Int(round(fractionalPage))
if (previousPage != page) {
currentPage = page;
}
}
deinit {
NotificationCenter.default.removeObserver(self)
print("deinittta")
}
}
extension SwiftPages: UIScrollViewDelegate {
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Load the pages that are now on screen
loadVisiblePages()
// The calculations for the animated bar's movements
// The offset addition is based on the width of the animated bar (button width times 0.8)
let offsetAddition = (containerVieww.frame.size.width / CGFloat(viewControllerIDs.count)) * 0.1
animatedBar.frame = CGRect(x: (offsetAddition + (scrollView.contentOffset.x / CGFloat(viewControllerIDs.count))), y: animatedBar.frame.origin.y, width: animatedBar.frame.size.width, height: animatedBar.frame.size.height)
}
}

Memory Usage with UICollectionView extremely high

I am having an issue with memory usage. Whenever I scroll or reload the data the memory usage keeps going up and never goes down. I have a feeling that for some reason the cells are not releasing any of the items displayed.
Any help would be greatly appreciated. I am quite sure I am doing something wrong, but I can't seem to find what.
Thank you in advance
Here is the code for creating my UICollectionView:
import Foundation
import UIKit
import CoreData
import Crashlytics
public class podCollectionView : UIViewController,UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout,UIPopoverPresentationControllerDelegate {
private var collectionView : UICollectionView = UICollectionView(frame: CGRectZero, collectionViewLayout: UICollectionViewFlowLayout()) // Initialization
private var inmates : NSArray = [];
private var context : NSManagedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext;
private var configuration = Configuration.sharedInstance;
private var titleView = UILabel();
private var database : FMDatabase = (UIApplication.sharedApplication().delegate as! AppDelegate).database!;
public override func viewDidLoad() {
getInmates();
super.viewDidLoad();
self.collectionView = podMainView(x: "1", y: "2");
self.collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "CellCell") // UICollectionViewCell
self.collectionView.backgroundColor = UIColor.clearColor();
self.collectionView.layer.cornerRadius = 5;
self.collectionView.layer.masksToBounds = true;
self.collectionView.delegate = self // delegate : UICollectionViewDelegate
self.collectionView.dataSource = self // datasource : UICollectionViewDataSource
self.view.addSubview(self.collectionView);
self.view = self.collectionView;
self.navigationItem.setHidesBackButton(true, animated:false);
var inmateRefresh: NSTimer!
gameTimer = NSTimer.scheduledTimerWithTimeInterval(120, target: self, selector: #selector(refreshDAta), userInfo: nil, repeats: true);
}
public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.inmates.count;
}
public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let retVal : UICollectionViewCell = self.collectionView.dequeueReusableCellWithReuseIdentifier("CellCell", forIndexPath: indexPath);
retVal.prepareForReuse();
retVal.addSubview(InmateSummary(inmate: self.inmates.objectAtIndex(indexPath.item) as! NSArray,parent: self));
return retVal;
}
private func getInmates(){
var totalInmates = 0;
var inmatesInArea = 0;
var inmatesOutOfArea = 0;
self.inmates = [];
do{
let tmpInmates : NSMutableArray = [];
let rs = try self.database.executeQuery("SELECT * FROM inmates WHERE podName='"+self.configuration.currentArea+"' ORDER BY suicideBlue DESC", values: nil)
while rs.next() {
let rowData : NSMutableArray = []
let colCount = Int(rs.columnCount()) as Int;
for i in 0 ..< colCount {
rowData.addObject(rs.objectForColumnName(rs.columnNameForIndex(Int32(i))));
}
if rowData[7] as! String == "" {
inmatesInArea = inmatesInArea + 1;
}else{
inmatesOutOfArea = inmatesOutOfArea + 1;
}
totalInmates = totalInmates + 1;
tmpInmates.addObject(rowData);
}
self.inmates = tmpInmates;
} catch {
CLSLogv("Error while loading inmates in main screen \(error)%#", getVaList(["three"]));
}
let barText = String(inmatesInArea) + "/" + String(inmatesOutOfArea) + " (" + String(totalInmates) + ")";
let buttonBack: UIButton = UIButton(type: UIButtonType.Custom) as UIButton
buttonBack.frame = CGRectMake(0, 0, 100, 40)
buttonBack.setTitle(barText, forState: .Normal);
let leftBarButtonItem: UIBarButtonItem = UIBarButtonItem(customView: buttonBack)
self.navigationItem.setLeftBarButtonItem(leftBarButtonItem, animated: false)
//self.database.close();
}
public func changePod(pod:String){
self.configuration.currentArea = pod;
self.titleView.text = pod + " ▼";
self.getInmates();
self.collectionView.reloadData();
}
public func refreshDAta(){
self.database.close();
self.database.open();
let inmateFetcer = InmateFetcher();
inmateFetcer.getUpdates();
self.getInmates();
//self.inmates = [];
self.collectionView.reloadData();
NSLog("DATA REFRESHED");
}
override public func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}
}
And here is the code for the views within the cells:
import Foundation
import UIKit
public class InmateSummary : UIView, UIPopoverPresentationControllerDelegate{
public var inmate:NSArray;
private var screenSize : CGRect = UIScreen.mainScreen().bounds;
private var configuration = Configuration.sharedInstance;
private var parent : podCollectionView;
init(inmate:NSArray, parent:podCollectionView){
let cellHeight = screenSize.height * 0.295;
let cellWidth = screenSize.width * 0.295;
self.inmate = inmate;
self.parent = parent;
super.init(frame: CGRect(x: 0, y: 0, width: cellWidth, height: cellHeight));
let aSelector : Selector = #selector(InmateSummary.inmateClicked(_:));
let tapGesture = UITapGestureRecognizer(target: self, action: aSelector);
tapGesture.numberOfTapsRequired = 1;
self.addGestureRecognizer(tapGesture);
self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1);
let topView = UIView(frame: CGRect(x: 0, y: 0, width: cellWidth, height: cellHeight*0.10));
topView.backgroundColor = UIColor.grayColor();
self.addSubview(topView);
let cellLab = UILabel(frame: CGRect(x: 0, y: 0, width: cellWidth, height: cellHeight*0.10));
cellLab.text = self.inmate[3] as? String;
cellLab.textColor = UIColor.whiteColor();
cellLab.font = UIFont.init(name:"Arial-BoldMT", size: 30);
cellLab.textAlignment = NSTextAlignment.Center;
self.addSubview(cellLab);
let sexLab = UILabel(frame: CGRect(x: cellWidth*0.75, y: 0, width: cellWidth*0.25, height: cellHeight*0.10));
sexLab.text = self.inmate[1] as? String
sexLab.textColor = UIColor.whiteColor();
sexLab.textAlignment = NSTextAlignment.Center;
self.addSubview(sexLab);
let greyView = UIView(frame: CGRect(x: 0, y: cellHeight*0.10, width: cellWidth, height: cellHeight*0.70));
greyView.backgroundColor = UIColor.grayColor();
self.addSubview(greyView);
if self.inmate[7] as? String == "" {
greyView.backgroundColor = UIColor.blackColor();
}
let eventLab = UILabel(frame: CGRect(x: cellWidth*0.75, y: 0, width: cellWidth*0.25, height: cellHeight*0.10));
eventLab.text = self.inmate[7] as? String;
eventLab.textColor = UIColor.whiteColor();
eventLab.textAlignment = NSTextAlignment.Center;
eventLab.adjustsFontSizeToFitWidth = true;
greyView.addSubview(eventLab);
let classLab = UILabel(frame: CGRect(x: 0, y: 0, width: cellWidth*0.25, height: cellHeight*0.10));
classLab.text = self.inmate[4] as? String;
classLab.textAlignment = NSTextAlignment.Center;
classLab.font = UIFont.init(name:"Arial-BoldMT", size: 20);
classLab.adjustsFontSizeToFitWidth = true;
if(classLab.text == "RISK"){
classLab.textColor = UIColor.yellowColor();
}else if(classLab.text == "7CLS"){
classLab.textColor = UIColor(red: 1.0, green:0.5, blue:0.0, alpha:1);
}else if(classLab.text == "8MAX"){
classLab.textColor = UIColor(red:1.0, green:0.0, blue:0.0, alpha:0.7);
}else{
classLab.textColor = UIColor.whiteColor();
}
greyView.addSubview(classLab);
var mugshot : UIImage = UIImage();
if (self.inmate[12] as? NSData) != nil {
mugshot = UIImage(data: (self.inmate[12] as? NSData)!)!;
}else{
NSLog("Inmate without mugshot: %#",self.inmate[2] as! String);
}
let mugshotView = UIImageView(frame: CGRect(x: cellWidth*0.16, y: cellHeight*0.09, width: cellWidth*0.66, height: cellHeight*0.5));
mugshotView.image = mugshot;
greyView.addSubview(mugshotView);
let bookingNumber = UILabel(frame: CGRect(x: cellWidth*0.25, y: cellHeight*0.545, width: cellWidth*0.50, height: cellHeight*0.15));
bookingNumber.text = self.inmate[2] as? String;
bookingNumber.textColor = UIColor.whiteColor();
bookingNumber.textAlignment = NSTextAlignment.Center;
bookingNumber.font = UIFont.init(name:"Arial-BoldMT", size: 20);
bookingNumber.adjustsFontSizeToFitWidth = true;
greyView.addSubview(bookingNumber);
let nameView = UIView(frame: CGRect(x: 0, y: cellHeight*0.75, width: cellWidth, height: cellHeight*0.25));
self.addSubview(nameView);
let maxRed = UIView(frame: CGRect(x: 0, y: 0, width: cellWidth*0.33, height: cellHeight*0.115));
maxRed.backgroundColor = UIColor.blackColor();
if (self.inmate[15] as! NSNumber == 1) {
maxRed.backgroundColor = UIColor.redColor();
}
nameView.addSubview(maxRed);
let suBlue = UIView(frame: CGRect(x: cellWidth*0.33, y: 0, width: cellWidth*0.33, height: cellHeight*0.115));
suBlue.backgroundColor = UIColor.blackColor();
if (self.inmate[18] as! NSNumber == 1) {
let aSelector : Selector = #selector(InmateSummary.suicideClicked(_:));
let tapGesture = UITapGestureRecognizer(target: self, action: aSelector);
tapGesture.numberOfTapsRequired = 1;
nameView.addGestureRecognizer(tapGesture);
suBlue.backgroundColor = UIColor.blueColor();
}
nameView.addSubview(suBlue);
let segGreen = UIView(frame: CGRect(x: cellWidth*0.66, y: 0, width: cellWidth*0.33, height: cellHeight*0.115));
segGreen.backgroundColor = UIColor.blackColor();
if (self.inmate[5] as! NSNumber == 1) {
segGreen.backgroundColor = UIColor.greenColor();
}
nameView.addSubview(segGreen);
let nameLab = UILabel(frame: CGRect(x: cellWidth*0.025, y: cellHeight*0.12, width: cellWidth*0.95, height: cellHeight*0.05));
nameLab.text = self.inmate[0] as? String;
nameLab.textAlignment = NSTextAlignment.Center;
nameLab.textColor = UIColor.whiteColor();
nameLab.font = UIFont.init(name:"Arial-BoldMT", size: 20);
nameLab.adjustsFontSizeToFitWidth = true;
nameView.addSubview(nameLab);
if(self.inmate[18] as! NSNumber == 1){
//NSLog("Suicide: %#",self.inmate);
let checkLab = UILabel(frame: CGRect(x: 0, y: cellHeight*0.17, width: cellWidth, height: cellHeight*0.07));
let formatter = NSDateFormatter()
formatter.dateFormat = "MM/dd HH:mm"
let tmpDate = NSDate(timeIntervalSince1970: (self.inmate[19] as! NSString).doubleValue)
let dateString = formatter.stringFromDate(tmpDate);
checkLab.text = (self.inmate[22] as? String)! + " - " + dateString;
checkLab.textAlignment = NSTextAlignment.Center;
checkLab.textColor = UIColor.whiteColor();
checkLab.font = UIFont.init(name:"Arial", size: 18);
checkLab.adjustsFontSizeToFitWidth = true;
nameView.addSubview(checkLab);
}
if self.inmate[1] as? String == "F" {
nameView.backgroundColor = UIColor.purpleColor();
}
self.layer.cornerRadius = 5;
self.layer.borderColor = UIColor.grayColor().CGColor;
self.layer.borderWidth = 1;
self.layer.masksToBounds = true;
}
func suicideClicked(sender:UITapGestureRecognizer!){
let podsChooser = ActivityChooser(parentView:self);
podsChooser.modalPresentationStyle = .Popover;
let popoverMenuViewController = podsChooser.popoverPresentationController
popoverMenuViewController!.permittedArrowDirections = .Any
popoverMenuViewController!.delegate = self
popoverMenuViewController!.sourceView = sender.view;
self.parent.presentViewController(
podsChooser,
animated: true,
completion: nil)
}
func inmateClicked (sender:InmateSummary){
NSLog("Inmate Clicked");
let vc = SingleInmateDisplay(inmate: inmate);
self.parent.navigationController!.pushViewController(vc,animated:false);
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

Resources