How hide a button (from a for loop)? - ios

I've created multiple buttons (12!) in a for loop.
And now I would hide one of these Buttons.
But I dont know how ;)
I used also button.tag, to get the label from every button I touch to fill the text in another label.
BTW: I used this for a PinCode Check and I want to hide the OK_Button until the PinCode is right.
var pinCode = [Int]()
var pinCodeCounter = 0
func pinCodeLabel() {
pinCodeCounter += 1
if pinCodeCounter == 1 {
pinLabel.text = "*"
}
if pinCodeCounter == 2 {
pinLabel.text = "**"
}
if pinCodeCounter == 3 {
pinLabel.text = "***"
}
if pinCodeCounter == 4 {
pinLabel.text = "****"
}
if pinCodeCounter == 0 {
pinLabel.text = ""
}
}
#IBOutlet weak var pinLabel: UILabel!
#IBOutlet weak var pinCodeCheck: UILabel!
#IBOutlet weak var continueToTimeControlView: UIButton!
#IBAction func pinCodeCorrect() {
if pinCode == [8, 1, 1, 8] {
pinCodeCheck.text = "PIN-Code Richtig"
pinCodeCheck.textColor = UIColor.black
continueToTimeControlView.isHidden = false
} else {
pinCodeCheck.text = "PIN-Code Falsch"
pinCodeCheck.textColor = UIColor.red
}
}
let btn_create = UIButton(type: .system)
#IBOutlet weak var attendanceView: UIView!
func btnAction(sender: UIButton!) {
switch (sender.tag) {
case 0:
pinCode.append(1)
print("1")
case 1:
pinCode.append(2)
print("2")
case 2:
pinCode.append(3)
print("3")
case 3:
pinCode.append(4)
print("4")
case 4:
pinCode.append(5)
print("5")
case 5:
pinCode.append(6)
print("6")
case 6:
pinCode.append(7)
print("7")
case 7:
pinCode.append(8)
print("8")
case 8:
pinCode.append(9)
print("9")
case 9:
pinCode.removeAll()
print("<-")
case 10:
pinCode.append(0)
print("0")
case 11:
pinCodeCorrect()
print(pinCode)
print("OK")
default:
print("")
}
pinCodeCorrect()
}
override func viewDidLoad() {
super.viewDidLoad()
continueToTimeControlView.isHidden = true
var x_axis = 37
var y_axis = 225
var z = 0
var rangeNumbers = ["1","2","3","4","5","6","7","8","9","<- ","0","OK"]
var btn_create = UIButton();
for _ in 1...4 {
for _ in 1...3 {
btn_create = UIButton(frame: CGRect(x: x_axis, y: y_axis, width: 90, height: 90))
btn_create.setTitle(rangeNumbers[z], for: .normal)
//btn_create?.backgroundColor = UIColor.lightGray
btn_create.setTitleColor(UIColor.black, for: .normal)
btn_create.layer.borderColor = UIColor.lightGray.cgColor
btn_create.layer.borderWidth = 1
btn_create.layer.cornerRadius = 45
btn_create.tag = z
btn_create.addTarget(attendanceView, action: #selector(btnAction), for: .touchUpInside)
self.view.addSubview(btn_create)
x_axis += 105
z += 1
}
x_axis = 37
y_axis += 100
}
}

var pinCode = [Int]()
var pinCodeCounter = 0
func pinCodeLabel() {
pinCodeCounter += 1
if pinCodeCounter == 1 {
pinLabel.text = "*"
}
if pinCodeCounter == 2 {
pinLabel.text = "**"
}
if pinCodeCounter == 3 {
pinLabel.text = "***"
}
if pinCodeCounter == 4 {
pinLabel.text = "****"
}
if pinCodeCounter == 0 {
pinLabel.text = ""
}
}
#IBOutlet weak var pinLabel: UILabel!
#IBOutlet weak var pinCodeCheck: UILabel!
#IBOutlet weak var continueToTimeControlView: UIButton!
#IBAction func pinCodeCorrect() {
if pinCode == [8, 1, 1, 8] {
pinCodeCheck.text = "PIN-Code Richtig"
pinCodeCheck.textColor = UIColor.black
continueToTimeControlView.isHidden = false
} else {
pinCodeCheck.text = "PIN-Code Falsch"
pinCodeCheck.textColor = UIColor.red
}
}
let btn_create = UIButton(type: .system)
#IBOutlet weak var attendanceView: UIView!
func btnAction(sender: UIButton!) {
switch (sender.tag) {
case 0:
pinCode.append(1)
print("1")
case 1:
pinCode.append(2)
print("2")
case 2:
pinCode.append(3)
print("3")
case 3:
pinCode.append(4)
print("4")
case 4:
pinCode.append(5)
print("5")
case 5:
pinCode.append(6)
print("6")
case 6:
pinCode.append(7)
print("7")
case 7:
pinCode.append(8)
print("8")
case 8:
pinCode.append(9)
print("9")
case 9:
pinCode.removeAll()
print("<-")
case 10:
pinCode.append(0)
print("0")
case 11:
pinCodeCorrect()
print(pinCode)
print("OK")
default:
print("")
}
pinCodeCorrect()
}
override func viewDidLoad() {
super.viewDidLoad()
continueToTimeControlView.isHidden = true
var x_axis = 37
var y_axis = 225
var z = 0
var rangeNumbers = ["1","2","3","4","5","6","7","8","9","<-","0","OK"]
var btn_create = UIButton();
for _ in 1...4 {
for _ in 1...3 {
btn_create = UIButton(frame: CGRect(x: x_axis, y: y_axis, width: 90, height: 90))
btn_create.setTitle(rangeNumbers[z], for: .normal)
//btn_create?.backgroundColor = UIColor.lightGray
btn_create.setTitleColor(UIColor.black, for: .normal)
btn_create.layer.borderColor = UIColor.lightGray.cgColor
btn_create.layer.borderWidth = 1
btn_create.layer.cornerRadius = 45
btn_create.tag = z
btn_create.addTarget(attendanceView, action: #selector(btnAction), for: .touchUpInside)
self.view.addSubview(btn_create)
x_axis += 105
z += 1
}
x_axis = 37
y_axis += 100
}
}
}

Related

how can i change the image in my collection view by tapping on media player in Swift

I have a collection view and a button in my view controller I want to change the image in my collection view by tapping on my button, but it is proving quite difficult.I have made it so when i click on my collection view my button image changes now i want to do vice versa. Any help would be appreciated
import UIKit
import SwiftAudioPlayer
import Soundable
import AVFoundation
import AVKit
import MediaPlayer
import Kingfisher
protocol poorBtn: AnyObject {
func poorBtnTapped(sender: UIButton!)
}
class SongsViewController: BaseViewController {
#IBOutlet weak var forYouView: UIView!
#IBOutlet weak var noSongsLbl: UILabel!
#IBOutlet weak var navView: UIView!
#IBOutlet weak var albumCollection: UICollectionView!
#IBOutlet weak var songsCollection: UICollectionView!
#IBOutlet weak var playBtn: UIButton!
#IBOutlet weak var playImg: UIImageView!
#IBOutlet weak var songProgress: UIProgressView!
#IBOutlet weak var startTime: UILabel!
#IBOutlet weak var endTime: UILabel!
#IBOutlet weak var songDetailView: UIView!
#IBOutlet weak var sliderProgress: UISlider!
#IBOutlet weak var forwardBtn: UIButton!
weak var delegate: poorBtn?
var play = false
var isplaying = false
let Parent = UIViewController()
var selectedIndex : Int?
let playList: NSMutableArray = NSMutableArray()
var albums : [String] = ["manHat", "manHat","manHat", "manHat"]
var albumLbl : [String] = ["George Harrison", "George Harrison","George Harrison",
"George Harrison"]
var songs : [String] = ["Geazy", "manHat","Geazy", "manHat"]
var playImage : [String] = ["wPause","wPause","wPause","wPause","wPause"]
var timer: Timer?
var index: Int = Int()
var avPlayer: AVPlayer!
var isPaused: Bool!
var didPlayed: Bool!
var isTapped: Bool!
var audio: AVAudioPlayer!
var playerItem: AVPlayerItem!
var music : [String] = ["https://p.scdn.co/mp3-
preview/6f9999d909b017eabef97234dd7a206355720d9d?
cid=d8a5ed958d274c2e8ee717e6a4b0971d","https://p.scdn.co/mp3-
preview/081447adc23dad4f79ba4f1082615d1c56edf5e1?
cid=d8a5ed958d274c2e8ee717e6a4b0971d"]
var counter: Timer?
var currentCellIndex = 0
var getSender: Int = Int()
var pop = false
var ploy = true
var newSender = 0
var isPlaying: Int?
var realSender: Int = Int()
var isPlay: Int?
var forPrev: Int?
var mainPlay: Int?
var playingIndex: Int?
lazy var viewModel:ForYouSongsViewModel = {
let viewModel = ForYouSongsViewModel()
viewModel.delegate = self
return viewModel
}()
var forSongs = [String]()
var currentIndex : Int?
var forImages = [ForYou]()
var albumImages = [Album]()
var albumId: String?
override func viewDidLoad() {
super.viewDidLoad()
sliderProgress.setValue(0, animated: true)
self.startLoading()
albumCollection.delegate = self
albumCollection.dataSource = self
songsCollection.delegate = self
songsCollection.dataSource = self
isPaused = false
songDetailView.layer.mask = maskLayer
viewModel.getForYouSongs()
// counter = Timer.scheduledTimer(timeInterval: 2, target: self, selector:
#selector(slider), userInfo: nil, repeats: true)
}
override func viewDidLayoutSubviews() {
self.setUpNavView()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
//test
#IBAction func backTap(_ sender: Any) {
self.dismiss(animated: true) {
// self.avPlayer = nil
self.timer?.invalidate()
}
}
#objc func slider() {
if forImages.isEmpty == true {
print("Sadly it's empty")
forYouView.isHidden = true
songsCollection.isHidden = true
noSongsLbl.text = "No Songs"
} else {
noSongsLbl.isHidden = true
if currentCellIndex < forSongs.count - 1 {
currentCellIndex+=1
}
else {
currentCellIndex = 0
}
songsCollection.scrollToItem(at: IndexPath(item: currentCellIndex, section: 0),
at: .right, animated: true)
}
}
#IBAction func playBtn(_ sender: UIButton) {
//delegate?.poorBtnTapped(sender: sender)
isPlay = 1
mainPlay = playingIndex
print(mainPlay)
if play == false {
self.startLoading()
guard let songUrlString = forSongs[self.index] as? String else {return}
guard let songUrl = URL(string:songUrlString) else{return}
print(songUrlString)
print(songUrl)
self.playSong(url: songUrl)
//NotificationCenter.default.post(name: Notification.Name("playSong"),
object: nil)
playImg.image = UIImage(named: "pause")
tick()
play = true
didPlayed = false
}
else if isplaying == true {
// playSaveSound()
avPlayer?.play()
playImg.image = UIImage(named: "pause")
// NotificationCenter.default.post(name: Notification.Name("playSong"),
object: nil)
isplaying = false
tick()
}
else {
avPlayer?.pause()
playImg.image = UIImage(named: "play")
isplaying = true
}
self.setupTimer()
NotificationCenter.default.post(name: Notification.Name("songPlay"), object: nil)
songsCollection.reloadData()
}
#IBAction func forwardBtn(_ sender: Any) {
self.startLoading()
self.nextTrack()
}
#IBAction func backBtn(_ sender: Any) {
self.startLoading()
self.prevTrack()
}
func playSong(url:URL) {
self.playerItem = AVPlayerItem(url: url)
self.avPlayer = AVPlayer(playerItem: playerItem)
self.avPlayer.automaticallyWaitsToMinimizeStalling = false
avPlayer!.volume = 1.0
avPlayer.play()
setupNowPlaying()
setupRemoteCommandCenter()
self.stopLoading()
}
func setupTimer(){
NotificationCenter.default.addObserver(self, selector:
#selector(self.didPlayToEnd), name: .AVPlayerItemDidPlayToEndTime, object: nil)
timer = Timer(timeInterval: 0.001, target: self, selector:
#selector(SongsViewController.tick), userInfo: nil, repeats: true)
RunLoop.current.add(timer!, forMode: RunLoop.Mode.common)
}
#objc func didPlayToEnd() {
self.startLoading()
self.nextTrack()
}
#IBAction func sliderTapped(_ sender: UISlider) {
let seconds : Int64 = Int64(sender.value)
let targetTime:CMTime = CMTimeMake(value: seconds, timescale: 1)
avPlayer?.seek(to: targetTime)
}
#objc func tick() {
//print(avPlayer)
if((avPlayer.currentItem?.asset.duration) != nil){
if let _ = avPlayer.currentItem?.asset.duration{}else{return}
if let _ = avPlayer.currentItem?.currentTime(){}else{return}
let currentTime1 : CMTime = (avPlayer.currentItem?.asset.duration)!
let seconds1 : Float64 = CMTimeGetSeconds(currentTime1)
let time1 : Float = Float(seconds1)
sliderProgress.minimumValue = 0
sliderProgress.maximumValue = time1
let currentTime : CMTime = (self.avPlayer?.currentTime())!
let seconds : Float64 = CMTimeGetSeconds(currentTime)
guard !(seconds.isNaN || seconds.isInfinite) else {
return
}
let time : Float = Float(seconds)
self.sliderProgress.value = time
endTime.text = self.formatTimeFromSeconds(totalSeconds:
[enter image description here]
[1]Int32(Float(Float64(CMTimeGetSeconds((self.avPlayer?.currentItem?.asset.duration)!
)))). )
startTime.text = self.formatTimeFromSeconds(totalSeconds:
Int32(Float(Float64(CMTimeGetSeconds((self.avPlayer?.currentItem?.currentTime())!))
)))
}else{
if let duration = (self.avPlayer?.currentItem?.duration) {
let secs = CMTimeGetSeconds(duration)
guard !(secs.isNaN || secs.isInfinite) else {
return
}
let secondsText = Int(secs.truncatingRemainder(dividingBy:
60.0))
let minutesText = Int(secs / 60)
self.endTime.text = "\(minutesText):\(secondsText)"
}
}
}
func nextTrack(){
if(index < forSongs.count-1){
index = index + 1
isPaused = false
playImg.image = UIImage(named: "pause")
self.playSong(url: URL(string:(forSongs[self.index] ))!)
}else{
index = 0
isPaused = false
playImg.image = UIImage(named: "pause")
self.playSong(url: URL(string:(forSongs[self.index] ))!)
}
}
func prevTrack(){
if(index > 0){
index = index - 1
isPaused = false
playImg.image = UIImage(named: "pause")
self.playSong(url: URL(string:(forSongs[self.index] as! String))!)
}
}
func formatTimeFromSeconds(totalSeconds: Int32) -> String {
let seconds: Int32 = totalSeconds%60
let minutes: Int32 = (totalSeconds/60)%60
// let hours: Int32 = totalSeconds/3600
return String(format: "%02d:%02d", minutes,seconds)
}
private func setUpNavView(){
let btnGradientLayer = CAGradientLayer()
let colorTop = UIColor(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha:
1.0).cgColor
let colorBottom = UIColor(red: 6.0/255.0, green: 47.0/255.0, blue: 79.0/255.0,
alpha: 1.0).cgColor
let startPoint = CGPoint(x: 0.0, y: 0.1)
let endPoint = CGPoint(x: 0.0, y: 1.0)
let frame = self.navView.bounds
btnGradientLayer.colors = [colorTop, colorBottom]
btnGradientLayer.startPoint = startPoint
btnGradientLayer.endPoint = endPoint
btnGradientLayer.frame = frame
navView.backgroundColor = .red
self.navView.layer.insertSublayer(btnGradientLayer, at: 0)
self.navView.clipsToBounds = false
}
#IBAction func playPauseButton(_ sender: UIButton!) {
self.selectedIndex = sender.tag
self.isTapped = true
}
//FOR NOTIFICATION
func setupNowPlaying() {
// Define Now Playing Info
var nowPlayingInfo = [String : Any]()
nowPlayingInfo[MPMediaItemPropertyTitle] = forImages[0].title
nowPlayingInfo[MPMediaItemPropertyArtist] = "G-Eazy"
if let movieArt = UIImage(named: "Geazy") {
nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize:
movieArt.size, requestHandler: {
imageSize in return movieArt })
}
nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = false
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] =
playerItem.currentTime().seconds
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] =
playerItem.asset.duration.seconds
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = avPlayer.rate
// Set the metadata
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
MPNowPlayingInfoCenter.default().playbackState = .playing
}
func setupRemoteCommandCenter() {
let commandCenter = MPRemoteCommandCenter.shared();
commandCenter.playCommand.isEnabled = true
commandCenter.playCommand.addTarget {event in
self.avPlayer.play()
self.playImg.image = UIImage(named: "pause")
self.setupTimer()
return .success
}
commandCenter.pauseCommand.isEnabled = true
commandCenter.pauseCommand.addTarget {event in
self.avPlayer.pause()
self.playImg.image = UIImage(named: "play")
// self.tick()
self.setupTimer()
return .success
}
}
}
extension SongsViewController: UICollectionViewDelegate, UICollectionViewDataSource,
UICollectionViewDelegateFlowLayout {
//FOR ALBUM COLLECTION
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection
section: Int) -> Int {
if collectionView == self.albumCollection {
return albumImages.count
}
return forSongs.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath:
IndexPath) -> UICollectionViewCell {
if collectionView == self.albumCollection {
let cellA = collectionView.dequeueReusableCell(withReuseIdentifier: "album", for:
indexPath) as! AlbumsCollectionViewCell
if albumImages.isEmpty != true {
let albumUrl = URL(string: albumImages[indexPath.row].image)
cellA.albumImg.kf.setImage(with: albumUrl)
cellA.albumLbl.text = albumImages[indexPath.row].name
}
return cellA
}
else {
let cellB = collectionView.dequeueReusableCell(withReuseIdentifier: "songs",
for: indexPath) as! ForYouCollectionViewCell
let songUrl = URL(string: forImages[indexPath.row].image)
cellB.forImg.kf.setImage(with: songUrl)
cellB.forButton.setImage(UIImage(named: playImage[indexPath.row]), for:
.normal)
cellB.songTitle.text = forImages[indexPath.row].title
cellB.forButton.tag = indexPath.row
if indexPath.row == isPlaying {
cellB.forButton.setImage(UIImage(named: "wPlay"), for: .normal)
} else {
cellB.forButton.setImage(UIImage(named: "wPause"), for: .normal)
}
// if isPlay == nil {
// print("I'm a noob")
//
// } else {
// if playImg.image == UIImage(named: "play") {
// cellB.forButton.setImage(UIImage(named: "wPause"), for:
.normal)
// } else {
// cellB.forButton.setImage(UIImage(named: "wPlay"), for: .normal)
// isPlay = nil
// }
//
}
if mainPlay != nil {
if cellB.forButton.image(for: .normal) == UIImage(named: "wPause") {
cellB.forButton.setImage(UIImage(named: "wPlay"), for: .normal)
} else {
cellB.forButton.setImage(UIImage(named: "wPause"), for: .normal)
mainPlay = nil
}
}
cellB.delegate = self
cellB.btnTapped
return cellB
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout:
UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath:
IndexPath) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "songs", for:
indexPath) as! ForYouCollectionViewCell
currentIndex = indexPath.row
if collectionView == self.albumCollection {
if didPlayed == false {
avPlayer.pause()
playImg.image = UIImage(named: "play")
//avPlayer = nil
timer?.invalidate()
self.presentAlbumCollectionController(fromController: self, withAId:
forImages[indexPath.row].album_id)
} else {
self.presentAlbumCollectionController(fromController: self, withAId:
forImages[indexPath.row].album_id)
}
}
isPlaying = indexPath.row
songsCollection.reloadData()
guard let songUrlString = forSongs[indexPath.row] as? String else {return}
guard let songUrl = URL(string:songUrlString) else{return}
print(songUrlString)
print(songUrl)
print(indexPath.row)
print(playList.count)
if play == false && getSender == indexPath.row {
self.playSong(url: songUrl)
tick()
playImg.image = UIImage(named: "pause")
play = true
getSender = indexPath.row
pop = false
ploy = true
} else if getSender == indexPath.row{
avPlayer?.pause()
playImg.image = UIImage(named: "play")
play = false
getSender = indexPath.row
isPlaying = nil
} else if newSender == indexPath.row && ploy == false {
playImg.image = UIImage(named: "pause")
self.playSong(url: songUrl)
tick()
play = false
pop = true
ploy = true
}
else if pop == true {
avPlayer?.pause()
playImg.image = UIImage(named: "play")
play = false
pop = false
isPlaying = nil
} else {
playImg.image = UIImage(named: "pause")
self.playSong(url: songUrl)
tick()
if realSender == getSender {
pop = false
}
ploy = true
getSender = indexPath.row
play = true
}
// if mainPlay != nil {
// if cell.forButton.image(for: .normal) == UIImage(named: "wPause") {
// cell.forButton.setImage(UIImage(named: "wPlay"), for: .normal)
// } else {
// cell.forButton.setImage(UIImage(named: "wPause"), for: .normal)
// }
// }
playingIndex = indexPath.row
self.setupTimer()
//
songsCollection.reloadData()
}
func collectionView(_ collectionView: UICollectionView,
willDisplay cell: UICollectionViewCell,
forItemAt indexPath: IndexPath) {
cell.alpha = 0
UIView.animate(withDuration: 0.8) {
cell.alpha = 1
}
}
/* func conditions() {
if play == false {
playImg.image = UIImage(named: "pause")
tick()
// SongTime()
play = true
}
else if isplaying == true {
// playSaveSound()
avPlayer?.play()
playImg.image = UIImage(named: "pause")
isplaying = false
tick()
//SongTime()
}
else {
avPlayer?.pause()
playImg.image = UIImage(named: "play")
isplaying = true
}
} */
}
extension SongsViewController:SongDelegate {
func songBtnTapped(sender: UIButton!) {
isPlaying = sender.tag
songsCollection.reloadData()
guard let songUrlString = forSongs[sender.tag] as? String else {return}
guard let songUrl = URL(string:songUrlString) else{return}
print(songUrlString)
print(songUrl)
print(sender.tag)
print(playList.count)
if play == false && getSender == sender.tag {
self.playSong(url: songUrl)
tick()
playImg.image = UIImage(named: "pause")
play = true
getSender = sender.tag
pop = false
ploy = true
} else if getSender == sender.tag{
avPlayer?.pause()
playImg.image = UIImage(named: "play")
play = false
getSender = sender.tag
isPlaying = nil
} else if newSender == sender.tag && ploy == false {
playImg.image = UIImage(named: "pause")
self.playSong(url: songUrl)
tick()
play = false
pop = true
ploy = true
}
else if pop == true {
avPlayer?.pause()
playImg.image = UIImage(named: "play")
play = false
pop = false
isPlaying = nil
} else {
playImg.image = UIImage(named: "pause")
self.playSong(url: songUrl)
tick()
if realSender == getSender {
pop = false
}
ploy = true
getSender = sender.tag
play = true
}
self.setupTimer()
}
}

How to loop a Slider value for height?

I successfully created a slider for user height in storyboard and the corresponding code to assign a value in the slider to each level of height but as you can see below, I had to manually copy & paste each new height variable to get it to work. I was curious how an expert would simplify this code? thanks!
*note - I removed the code for height 5'2 to 6'4 to not take up so much space.
'''
#IBOutlet weak var yourHeightEquals: UILabel!
#IBOutlet weak var heightSliderOutlet: UISlider!
#IBAction func heightSliderAction(_ sender: UISlider) {
heightSliderOutlet.value = roundf(heightSliderOutlet.value)
let yourHeightText: String = "Your Height: "
if heightSliderOutlet.value == 0 {
let yourHeightString = "Choose Your Height"
yourHeightEquals.text = yourHeightString
}
else if heightSliderOutlet.value == 1 {
let yourHeightString = "<5'0"
yourHeightEquals.text = yourHeightText + yourHeightString
}
else if heightSliderOutlet.value == 2 {
let yourHeightString = "5'0"
yourHeightEquals.text = yourHeightText + yourHeightString
}
else if heightSliderOutlet.value == 3 {
let yourHeightString = "5'1"
yourHeightEquals.text = yourHeightText + yourHeightString
}
.......
else if heightSliderOutlet.value == 19 {
let yourHeightString = "6'5"
yourHeightEquals.text = yourHeightText + yourHeightString
}
else if heightSliderOutlet.value == 20 {
let yourHeightString = ">6'5"
yourHeightEquals.text = yourHeightText + yourHeightString
}
}
'''
You can use a switch statement like this.
#IBOutlet weak var heightSliderOutlet: UISlider!
#IBOutlet weak var yourHeightEquals: UILabel!
#IBAction func heightSliderAction(_ sender: UISlider) {
let value = roundf(heightSliderOutlet.value)
switch value {
case 0:
yourHeightEquals.text = "Choose Your Height"
case 1:
yourHeightEquals.text = "Your Height : <5'0"
case 2...19:
let height = 5.0 + ((value - 2) * 0.1)
yourHeightEquals.text = "Your Height : \(height)"
default:
yourHeightEquals.text = "Your Height: >6'5"
}
}
Update - the switch code above only worked for a metric system - I had to modify it a bit for feet & inches, still much cleaner than my original code!
#IBOutlet weak var yourHeightEquals: UILabel!
#IBOutlet weak var heightSliderOutlet: UISlider!
#IBAction func heightSliderAction(_ sender: UISlider) {
let value = roundf(heightSliderOutlet.value)
switch value {
case 0:
yourHeightEquals.text = "Choose Your Height"
case 1:
yourHeightEquals.text = "Your Height: <5'0"
case 2...11:
let height = 5.0 + ((value - 2) * 0.1)
let heightstring = String(height)
let heightfoot = heightstring.dropLast(2)
let heightinch = heightstring.dropFirst(2)
let heightfootinch = heightfoot + "'" + heightinch
yourHeightEquals.text = "Your Height: \(heightfootinch)"
case 12:
yourHeightEquals.text = "Your Height: 5'10"
case 13:
yourHeightEquals.text = "Your Height: 5'11"
case 14...19:
let height = 6.0 + ((value - 14) * 0.1)
let heightstring = String(height)
let heightfoot = heightstring.dropLast(2)
let heightinch = heightstring.dropFirst(2)
let heightfootinch = heightfoot + "'" + heightinch
yourHeightEquals.text = "Your Height: \(heightfootinch)"
default:
yourHeightEquals.text = "Your Height: >6'5"
}
}

UITableViewCell constraints not updated till I scroll tableview

Following is my code to update view height inside tableview cell
override func layoutSubviews() {
super.layoutSubviews()
layout()
}
fileprivate func layout() {
rootFlexContainer.frame.size.width = frame.width - 20
rootFlexContainer.flex.layout(mode: .adjustHeight)
if(rootFlexContainer.frame.height != 0) {
tagsHeight.constant = rootFlexContainer.frame.height
}
}
although this is not reflected till I scroll i.e is cell is recreated. How to update constraint inside TableViewCell of a view?
here is entire tableviewcell code
import UIKit
import FlexLayout
import SDWebImage
class StoreListTableViewCell: UITableViewCell {
#IBOutlet weak var menuLbl: UILabel!
#IBOutlet weak var menuView: UIView!
#IBOutlet weak var cellBgview: UIView!
#IBOutlet weak var storeImg: UIImageView!
#IBOutlet weak var storeLocation: UILabel!
#IBOutlet weak var storeTitle: UILabel!
#IBOutlet weak var cellContainer: UIView!
#IBOutlet weak var stackView: UIStackView!
#IBOutlet weak var tagsHeight: NSLayoutConstraint!
var storeImgStr = ""
var storeTitleStr = ""
var storeLocationStr = ""
var score : Double = 0.0
var tagsStr = ""
var isMenuAvailble = 0
var retailerTags: [String]?
var cashbackString = ""
fileprivate let rootFlexContainer = UIView()
#IBOutlet weak var tagsView: UIView!
#IBOutlet weak var ratingBtn: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
self.layoutIfNeeded()
cellBgview.clipsToBounds = true
cellBgview.layer.cornerRadius = 5
cellContainer.layer.shadowColor = UIColor.lightGray.cgColor
cellContainer.layer.shadowOpacity = 0.5
cellContainer.layer.shadowRadius = 5.0
cellContainer.layer.shadowOffset = CGSize(width: 0, height: 2)
cellContainer.backgroundColor = UIColor.clear
cellContainer.layer.cornerRadius = 5.0
cellContainer.layer.borderColor = UIColor.white.cgColor
cellContainer.layer.borderWidth = 0.5
ratingBtn.layer.borderWidth = 1
ratingBtn.layer.cornerRadius = 5
tagsView.addSubview(rootFlexContainer)
//cellContainer.layer.shadowPath = UIBezierPath(rect: cellBgview.bounds).cgPath
}
func setSetupStoreUI() {
if isMenuAvailble == 1 {
menuView.isHidden = false
menuView.layer.cornerRadius = 10
} else {
menuView.isHidden = true
}
storeTitle.text = storeTitleStr
// storeTitle.sizeToFit()
storeLocation.text = storeLocationStr
//storeLocation.sizeToFit()
//.filter{ $0.name != " " }
//storeImg.sd_imageIndicator = SDWebImageActivityIndicator.gray
storeImg.backgroundColor = UIColor.hexStringToUIColor(hex: AppStrings.placeHolderColor)
if let url = URL(string: storeImgStr.encoded), !(storeImgStr.isEmpty) {
self.storeImg.sd_setImage(with: url)
}
menuLbl.text = AppLocalString.PREORDER_TEXT.localized()
menuLbl.font = FontStyle.ProximaNovaBold(size: 12)
storeTitle.font = FontStyle.ProximaNovaSemibold(size: 14)
storeLocation.font = FontStyle.ProximaNovaRegular(size: 12)
storeLocation.textColor = .gray
// ratingBtn.isHidden = (score == 0)
ratingBtn.setTitle(score == 0 ? "-" : String(format: "%.1f", score), for: .normal)
ratingBtn.backgroundColor = UIColor.hexStringToUIColor(hex: Utility.getRatingColor(rating: score))
ratingBtn.layer.borderColor = UIColor.hexStringToUIColor(hex: Utility.getRatingColor(rating: score)).cgColor
rootFlexContainer.subviews.forEach({ $0.removeFromSuperview() })
//tagsView.willRemoveSubview(rootFlexContainer)
//rootFlexContainer.frame = tagsView.frame
//tagsView.addSubview(rootFlexContainer)
rootFlexContainer.flex.direction(.row).wrap(.wrap).alignSelf(.auto).justifyContent(.start).paddingRight(2).define { (flex) in
for i in 0..<((retailerTags?.count ?? 0) > 3 ? 3 : (retailerTags?.count ?? 0)) {
let nameLabel = UIButton()
nameLabel.isUserInteractionEnabled = false
nameLabel.setTitle((retailerTags?[i] ?? "").trim(), for: .normal)
nameLabel.setTitleColor(.black, for: .normal)
nameLabel.titleLabel?.font = FontStyle.ProximaNovaRegular(size: 11)
nameLabel.contentEdgeInsets = UIEdgeInsets(top: 1.5, left: 4, bottom: 1.5, right:4)
nameLabel.layer.borderColor = UIColor.hexStringToUIColor(hex: AppStrings.grayBorderColor).cgColor
nameLabel.layer.cornerRadius = 8
nameLabel.layer.borderWidth = 1.0
nameLabel.sizeToFit()
flex.addItem(nameLabel).margin(2)
}
if cashbackString != "" {
let cashbackLabel = UIButton()
cashbackLabel.backgroundColor = UIColor.hexStringToUIColor(hex: AppStrings.orangeCashbackColor)
cashbackLabel.isUserInteractionEnabled = false
cashbackLabel.setTitle(cashbackString, for: .normal)
cashbackLabel.setTitleColor(.black, for: .normal)
cashbackLabel.titleLabel?.font = FontStyle.ProximaNovaRegular(size: 10)
cashbackLabel.contentEdgeInsets = UIEdgeInsets(top: 1.5, left: 5, bottom: 1.5, right: 5)
cashbackLabel.layer.cornerRadius = 5
cashbackLabel.layer.borderWidth = 0
cashbackLabel.sizeToFit()
flex.addItem(cashbackLabel).margin(2)
}
}
rootFlexContainer.flex.layout()
if retailerTags?.count ?? 0 == 0 {
tagsView.isHidden = true
} else {
tagsView.isHidden = false
}
}
override func layoutSubviews() {
super.layoutSubviews()
layout()
}
fileprivate func layout() {
rootFlexContainer.frame.size.width = frame.width - 20
rootFlexContainer.flex.layout(mode: .adjustHeight)
if(rootFlexContainer.frame.height != 0) {
tagsHeight.constant = rootFlexContainer.frame.height
}
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Following is view hierarchy from stroryboard
A few observations -
1. Unnecessary layoutIfNeeded() call inside awakeFromNib()
override func awakeFromNib() {
super.awakeFromNib()
/*
self.layoutIfNeeded() // Not Necessary, Remove it.
*/
// No other changes to current implementation
}
2. Following should not be necessary, remove it.
/* Not necessary, Remove it.
override func layoutSubviews() {
super.layoutSubviews()
layout()
}
fileprivate func layout() {
rootFlexContainer.frame.size.width = frame.width - 20
rootFlexContainer.flex.layout(mode: .adjustHeight)
if(rootFlexContainer.frame.height != 0) {
tagsHeight.constant = rootFlexContainer.frame.height
}
}
*/
3. In the method, where you populate all the details, make following changes
func setSetupStoreUI() {
// No changes to current implementation
/* Remove this, we will update later
rootFlexContainer.flex.layout()
*/
if retailerTags?.count ?? 0 == 0 {
tagsView.isHidden = true
} else {
tagsView.isHidden = false
}
// Copied as is from `layout()`
rootFlexContainer.frame.size.width = frame.width - 20
rootFlexContainer.flex.layout(mode: .adjustHeight)
if (rootFlexContainer.frame.height != 0) {
tagsHeight.constant = rootFlexContainer.frame.height
}
// do a manual layout (on contentView, NOT self)
self.contentView.layoutIfNeeded()
}
You have to tell the table view controller that your cell height has changed.
Most common methods are protocol/delegate pattern or (swift preferred) closures.
For example...
In your cell class:
class MyTableViewCell: UITableViewCell {
// "callback" closure
var cellHeightChanged: (()->())?
// whatever happens that you need to change the cell height
func heightChanged() -> Void {
tagsHeight.constant = rootFlexContainer.frame.height
cellHeightChanged?()
}
}
Then, in your controller, in cellForRowAt:
cell.cellHeightChanged = {
tableView.performBatchUpdates(nil, completion: nil)
}

Individual Labels update value when swiped

Ive got my swipe functionality working now on individual labels due to some great help! Now I just need each of those labels to update individually when swiped, so each label has its own seperate counter and doesnt effect the other ones.
heres my code:
import UIKit
class ViewController: UIViewController {
var counter = 0
#IBOutlet weak var label1: UILabel!
#IBOutlet weak var label2: UILabel!
#IBOutlet weak var label3: UILabel!
var counters: [UILabel: Int] = [:]
override func viewDidLoad() {
super.viewDidLoad()
for label: UILabel in [label1, label2, label3] {
counters[label] = 0
for direction: UISwipeGestureRecognizerDirection in [.up, .down, .left, .right] {
let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(didSwipe(_:)))
swipeGesture.direction = direction
label.addGestureRecognizer(swipeGesture)
label.isUserInteractionEnabled = true
label.isMultipleTouchEnabled = true
}
}
}
#objc func didSwipe(_ gestureRecognizer: UISwipeGestureRecognizer) {
guard let label = gestureRecognizer.view as? UILabel else { return }
debugPrint("\(gestureRecognizer.direction)")
switch gestureRecognizer.direction {
case .up:
counters[label] = counters[label]! + 5
print(counters)
case .down:
counters[label] = 0
print(counters)
case .left:
counters[label] = counters[label]! - 1
print(counters)
case .right:
counters[label] = counters[label]! + 1
print(counters)
default:
label.text = "0"
}
}
}
You need to call
label.text = "\(counters[label]!)"
At the end of your switch statement. This should work.
I see how, set the label of the text at the end of the gesture.
label.text = “(counters[label]!)”
For example,
#objc func didSwipe(_ gestureRecognizer: UISwipeGestureRecognizer) {
guard let label = gestureRecognizer.view as? UILabel else { return }
debugPrint("\(gestureRecognizer.direction)")
switch gestureRecognizer.direction {
case .up:
counters[label] = counters[label]! + 5
print(counters)
case .down:
counters[label] = 0
print(counters)
case .left:
counters[label] = counters[label]! - 1
print(counters)
case .right:
counters[label] = counters[label]! + 1
print(counters)
default:
counters[label] = 0
}
label.text = “\(counters[label]!)”
}

Use my Swipe gesture function on multiple UILabels swift

Im a newbie, ive managed to find and adapt code so that when i swipe a label, the value of that label changes. Now my func only relates to one particular label, but i want to make multiple labels have the exact same function, its a statistic taking label, how do i modify/apply the func to many different labels?
Here is my code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var counterLabel: UILabel!
#IBOutlet weak var kickLabel: UILabel!
var counter = 0
var swipeGesture = UISwipeGestureRecognizer()
override func viewDidLoad() {
super.viewDidLoad()
let direction: [UISwipeGestureRecognizerDirection] = [.up, .down, .left, .right]
for dir in direction{
swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(self.counterLabel(_:)))
counterLabel.addGestureRecognizer(swipeGesture)
swipeGesture.direction = dir
counterLabel.isUserInteractionEnabled = true
counterLabel.isMultipleTouchEnabled = true
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#objc func counterLabel(_ sender:UISwipeGestureRecognizer){
UIView.animate(withDuration: 1.0) {
if sender.direction == .right{
print("Swiped Right")
self.counter += 1
print(self.counter)
self.counterLabel.text = String(self.counter)
}else if sender.direction == .left{
print("Swiped Left")
print(self.counter)
self.counter -= 1
self.counterLabel.text = String(self.counter)
}else if sender.direction == .up{
print("Swiped Up")
self.counter += 5
self.counterLabel.text = String(self.counter)
}else if sender.direction == .down{
print("Swiped Down")
self.counter = 0
self.counterLabel.text = String(self.counter)
}
}
}
}
UISwipeGestureRecognizer has the view the gesture is applied to. Cast this to a UILabel.
(You might also want to check the gesture state for better performance.)
class ViewController: UIViewController {
#IBOutlet weak var label1: UILabel!
#IBOutlet weak var label2: UILabel!
var counters: [UILabel: Int] = [:]
override func viewDidLoad() {
super.viewDidLoad()
for label: UILabel in [label1, label2] {
counters[label] = 0
for direction: UISwipeGestureRecognizerDirection in [.up, .down, .left, .right] {
let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(didSwipe(_:)))
swipeGesture.direction = direction
label.addGestureRecognizer(swipeGesture)
}
}
}
#objc func didSwipe(_ gestureRecognizer: UISwipeGestureRecognizer) {
guard gestureRecognizer.state == .recognized else { return }
guard let label = gestureRecognizer.view as? UILabel else { return }
debugPrint("\(gestureRecognizer.direction)")
switch gestureRecognizer.direction {
case .up:
counters[label] = counters[label] + 1
label.text = "Up"
case .down:
label.text = "Down"
case .left:
label.text = "Left"
case .right:
label.text = "Right"
default:
label.text = "???"
}
}
}

Resources