swift 3.0 UISlider left thumbs - swift

This's code,
slider = UISlider(frame: CGRect(x: 80,y: 9.5,width: UIScreen.main.bounds.width - 160,height: 15))
slider.minimumTrackTintColor = UIColor.orange
slider.isContinuous = false
slider.addTarget(self, action: #selector(pageChange), for: .valueChanged)
slider.setThumbImage(UIImage(named:"RM_3"), for: .normal)
bottomBar?.addSubview(slider)
How to clean up the left thumbs???

IN Swift 3.0
import UIKit
class DBSlider: UISlider {
#IBInspectable var thumbImage: UIImage?
#IBInspectable var minTrackColor:UIColor?
#IBInspectable var maxTrackColor:UIColor?
// MARK: Lifecycle
override func awakeFromNib() {
super.awakeFromNib()
if let thumbImage = thumbImage
{0
self.setThumbImage(thumbImage, for: .normal)
}
if let minTrackColor = minTrackColor
{
self.minimumTrackTintColor = minTrackColor
}
if let maxTrackColor = maxTrackColor
{
self.maximumTrackTintColor = maxTrackColor
}
}
}

Related

inputAccessoryView sizing problem on iPhones without physical home button

inputAccessoryView's background view is falling under its own textField and profile picture imageView.
It works fine on regular screen iPhones, but on new iPhones with notches it looks like this:
Here's how it looks animated when keyboard appears: Transition animation on becomeFirstResponder()
Here's my tableView in which I'm trying to add accessoryView:
import UIKit
import SDWebImage
class CommentsTableViewController: UITableViewController {
let viewModel = CommentsViewModel()
let postID: String
let postCaption: String
let postDate: Date
let postAuthor: ZoogramUser
var keyboardAccessoryView: CommentAccessoryView = {
let commentAccessoryView = CommentAccessoryView()
return commentAccessoryView
}()
init(post: UserPost) {
self.postID = post.postID
self.postCaption = post.caption
self.postDate = post.postedDate
self.postAuthor = post.author
super.init(style: .grouped)
self.tableView.register(PostCommentsTableViewCell.self, forCellReuseIdentifier: PostCommentsTableViewCell.identifier)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Comments"
keyboardAccessoryView.delegate = self
configureKeyboardAccessoryView()
viewModel.getComments(for: self.postID) {
self.tableView.reloadData()
}
tableView.backgroundColor = .systemBackground
tableView.keyboardDismissMode = .interactive
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 100
tableView.allowsSelection = false
tableView.separatorStyle = .none
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
becomeFirstResponder()
}
override var inputAccessoryView: UIView? {
keyboardAccessoryView.heightAnchor.constraint(greaterThanOrEqualToConstant: 60).isActive = true
keyboardAccessoryView.backgroundColor = .systemOrange
return keyboardAccessoryView
}
override var canBecomeFirstResponder: Bool {
return true
}
func configureKeyboardAccessoryView() {
guard let photoURL = AuthenticationManager.shared.getCurrentUserProfilePhotoURL() else {
return
}
keyboardAccessoryView.userProfilePicture.sd_setImage(with: photoURL)
}
}
And here's code for my CommentAccessoryView which I use to override inputAccessoryView:
import UIKit
protocol CommentAccessoryViewProtocol {
func postButtonTapped(commentText: String)
}
class CommentAccessoryView: UIView {
var delegate: CommentAccessoryViewProtocol?
var userProfilePicture: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
imageView.clipsToBounds = true
imageView.backgroundColor = .secondarySystemBackground
imageView.contentMode = .scaleAspectFill
return imageView
}()
var commentTextField: AccessoryViewTextField = {
let textField = AccessoryViewTextField()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.backgroundColor = .systemBackground
textField.placeholder = "Enter comment"
textField.clipsToBounds = true
textField.layer.borderWidth = 1
textField.layer.borderColor = UIColor.placeholderText.cgColor
return textField
}()
var postButton: UIButton = {
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.widthAnchor.constraint(equalToConstant: 30).isActive = true
button.heightAnchor.constraint(equalToConstant: 30).isActive = true
button.clipsToBounds = true
button.layer.cornerRadius = 30/2
button.setImage(UIImage(systemName: "arrow.up.circle.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 35)), for: .normal)
button.tintColor = .systemBlue
button.addTarget(self, action: #selector(didTapPostButton), for: .touchUpInside)
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupConstraints()
backgroundColor = .systemBackground
commentTextField.rightView = postButton
commentTextField.rightViewMode = .always
autoresizingMask = .flexibleHeight
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
setViewCornerRadius()
}
func setViewCornerRadius() {
userProfilePicture.layer.cornerRadius = userProfilePicture.frame.height / 2
commentTextField.layer.cornerRadius = commentTextField.frame.height / 2
}
func setupConstraints() {
self.addSubviews(userProfilePicture, commentTextField)
NSLayoutConstraint.activate([
userProfilePicture.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10),
userProfilePicture.centerYAnchor.constraint(equalTo: self.safeAreaLayoutGuide.centerYAnchor),
userProfilePicture.widthAnchor.constraint(equalToConstant: 40),
userProfilePicture.heightAnchor.constraint(equalToConstant: 40),
commentTextField.leadingAnchor.constraint(equalTo: userProfilePicture.trailingAnchor, constant: 10),
commentTextField.centerYAnchor.constraint(equalTo: userProfilePicture.centerYAnchor),
commentTextField.heightAnchor.constraint(equalToConstant: 40),
commentTextField.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -10),
])
}
override var intrinsicContentSize: CGSize {
return CGSize.zero
}
#objc func didTapPostButton() {
guard let text = commentTextField.text else {
return
}
commentTextField.resignFirstResponder()
delegate?.postButtonTapped(commentText: text)
}
}
I've spent days trying to google a fix for that but nothing helps.
There were posts saying they were able to fix something similar by setting customView's bottom constraint to a safe area with the following method:
override func didMoveToWindow() {
if #available(iOS 11.0, *) {
if let window = window {
let bottomAnchor = bottomAnchor.constraint(lessThanOrEqualToSystemSpacingBelow: window.safeAreaLayoutGuide.bottomAnchor, multiplier: 1.0)
bottomAnchor.isActive = true
}
}
}
But when I use it, AutoLayout starts complaining.
UPDATE: I did what HangarRash recommended, changed CommentAccessoryView from UIView to UIInputView and centering profileImageView and textField to view itself and not to safe area. Now it's a little bit better, but seems to ignore safe area, inputAccessoryView should be above Home indicator but lies beneath it instead. Looking at last cell in TableView and Scroll indicator, it seems like TableView also isn't aware of inputAccessoryView and goes under it.

Custom Segment Control with UIView, only the first button works

I realized a Custom Segment Control with UIView, only the first button works.
When I click on the other buttons, they don't change color, and the first button stays with the active background color.
I would like to give the buttons an on / off effect, but only the first button remains on.
I believe the problem is inside the method:
func didSelectButton (at index: Int) {
but I can't find what's missing
import UIKit
#IBDesignable class CustomSegmentedView: UIView {
#IBInspectable var selectedBackgroundColor = Colors.colorViolet1 {
didSet {
self.slideView.backgroundColor = selectedBackgroundColor
}
}
#IBInspectable var selectedTextColor: UIColor = UIColor.white
#IBInspectable var buttonText1: String = ConstantFile.buttonMonitoring {
didSet {
self.buttonTitles[0] = buttonText1
}
}
#IBInspectable var buttonText2: String = ConstantFile.buttonAlert {
didSet {
self.buttonTitles[1] = buttonText2
}
}
#IBInspectable var buttonText3: String = ConstantFile.buttonActivities {
didSet {
self.buttonTitles[2] = buttonText3
}
}
#IBInspectable var buttonText4: String = ConstantFile.buttonSettings {
didSet {
self.buttonTitles[3] = buttonText4
}
}
#IBInspectable var image1: UIImage = UIImage() {
didSet {
self.buttonImages[0] = image1
}
}
#IBInspectable var image2: UIImage = UIImage() {
didSet {
self.buttonImages[1] = image2
}
}
#IBInspectable var image3: UIImage = UIImage() {
didSet {
self.buttonImages[2] = image3
}
}
#IBInspectable var image4: UIImage = UIImage() {
didSet {
self.buttonImages[3] = image4
}
}
#IBInspectable var image1Selected: UIImage = UIImage() {
didSet {
self.buttonSelectImages[0] = image1Selected
}
}
#IBInspectable var image2Selected: UIImage = UIImage() {
didSet {
self.buttonSelectImages[1] = image2Selected
}
}
#IBInspectable var image3Selected: UIImage = UIImage() {
didSet {
self.buttonSelectImages[2] = image3Selected
}
}
#IBInspectable var image4Selected: UIImage = UIImage() {
didSet {
self.buttonSelectImages[3] = image4Selected
}
}
#IBInspectable var startingIndex: Int = 0 {
didSet {
if startingIndex > 3 {
startingIndex = 3
self.didSelectButton(at: startingIndex)
} else if startingIndex < 0 {
startingIndex = 0
self.didSelectButton(at: startingIndex)
} else {
self.didSelectButton(at: startingIndex)
}
}
}
lazy var button1: UIButton = {
let button = UIButton(type: .custom)
button.setTitle("", for: .normal)
button.titleLabel?.font = UIFont.fontHelveticaBold14
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -15, bottom: 0, right: 0)
return button
}()
lazy var button2: UIButton = {
let button = UIButton(type: .custom)
button.setTitle("", for: .normal)
button.titleLabel?.font = UIFont.fontHelveticaBold14
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -15, bottom: 0, right: 0)
return button
}()
lazy var button3: UIButton = {
let button = UIButton(type: .custom)
button.setTitle("", for: .normal)
button.titleLabel?.font = UIFont.fontHelveticaBold14
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -15, bottom: 0, right: 0)
return button
}()
lazy var button4: UIButton = {
let button = UIButton(type: .custom)
button.setTitle("", for: .normal)
button.titleLabel?.font = UIFont.fontHelveticaBold14
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -15, bottom: 0, right: 0)
return button
}()
lazy var stackView: UIStackView = UIStackView(arrangedSubviews: [])
lazy var slideView: UIView = {
var view = UIView(frame: CGRect.zero)
view.backgroundColor = self.selectedBackgroundColor
return view
}()
private var currentIndex: Int = 0
private var buttons: [UIButton] = []
private lazy var buttonTitles:[String] = [buttonText1, buttonText2, buttonText3, buttonText4]
private lazy var buttonImages:[UIImage] = [image1, image2, image3, image4]
private lazy var buttonSelectImages:[UIImage] = [image1Selected, image2Selected, image3Selected, image4Selected]
var delegate: CustomSegmentedViewDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupView()
}
private func setupView() {
self.buttons = [button1, button2, button3, button4]
self.buttonTitles = [buttonText1, buttonText2, buttonText3, buttonText4]
self.buttonImages = [image1, image2, image3, image4]
self.buttonSelectImages = [image1Selected, image2Selected, image3Selected, image4Selected]
button1.sizeToFit()
button2.sizeToFit()
button3.sizeToFit()
button4.sizeToFit()
stackView.addArrangedSubview(button1)
stackView.addArrangedSubview(button2)
stackView.addArrangedSubview(button3)
stackView.addArrangedSubview(button4)
stackView.axis = .horizontal
stackView.distribution = .fillProportionally
stackView.alignment = .fill
stackView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(slideView)
self.addSubview(stackView)
stackView.pinEdges(to: self)
button1.addTarget(self, action: #selector(CustomSegmentedView.buttonTapped(sender:)), for: .touchUpInside)
button2.addTarget(self, action: #selector(CustomSegmentedView.buttonTapped(sender:)), for: .touchUpInside)
button3.addTarget(self, action: #selector(CustomSegmentedView.buttonTapped(sender:)), for: .touchUpInside)
button4.addTarget(self, action: #selector(CustomSegmentedView.buttonTapped(sender:)), for: .touchUpInside)
button1.setTitle("", for: .normal)
button2.setTitle("", for: .normal)
button3.setTitle("", for: .normal)
button4.setTitle("", for: .normal)
}
override func layoutSubviews() {
super.layoutSubviews()
button1.setImage(buttonImages[0], for: .normal)
button2.setImage(buttonImages[1], for: .normal)
button3.setImage(buttonImages[2], for: .normal)
button4.setImage(buttonImages[3], for: .normal)
self.setupFirstSelection()
}
#objc func buttonTapped(sender :UIButton!) {
switch sender {
case button1:
didSelectButton(at: 0)
break
case button2:
didSelectButton(at: 1)
break
case button3:
didSelectButton(at: 2)
break
case button4:
didSelectButton(at: 3)
break
default:
break
}
}
func didSelectButton(at index: Int) {
self.delegate?.didSelectPage(index: index)
let oldButton = self.buttons[self.currentIndex]
let newButton = self.buttons[index]
newButton.alpha = 0.0
oldButton.setImage(self.buttonImages[self.currentIndex], for: .normal)
newButton.setImage(self.buttonSelectImages[index], for: .normal)
UIView.animate(withDuration: 0.1) {
oldButton.setTitle("", for: .normal)
newButton.setTitle(self.buttonTitles[index], for: .normal)
self.stackView.layoutSubviews()
self.layoutIfNeeded()
newButton.alpha = 1.0
}
UIView.animate(withDuration: 0.2, delay: 0, options: [], animations: {
self.slideView.frame = newButton.frame
self.layoutIfNeeded()
}, completion: nil)
self.currentIndex = index
}
func setupFirstSelection() {
let index = self.startingIndex
let newButton = self.buttons[index]
newButton.setTitle(self.buttonTitles[index], for: .normal)
newButton.setImage(self.buttonSelectImages[index], for: .normal)
self.stackView.layoutSubviews()
self.slideView.frame = newButton.frame
self.slideView.layer.cornerRadius = self.slideView.frame.height/2.0
self.currentIndex = index
}
}
extension UIView {
func pinEdges(to other: UIView) {
leadingAnchor.constraint(equalTo: other.leadingAnchor).isActive = true
trailingAnchor.constraint(equalTo: other.trailingAnchor).isActive = true
topAnchor.constraint(equalTo: other.topAnchor).isActive = true
bottomAnchor.constraint(equalTo: other.bottomAnchor).isActive = true
}
}
protocol CustomSegmentedViewDelegate {
func didSelectPage(index: Int)
}
issue is in your layoutSubviews() you call every time when you call layoutSubviews() this function automatically set first self.setupFirstSelection()
replace layoutSubviews() by commenting self.setupFirstSelection()
override func layoutSubviews() {
super.layoutSubviews()
button1.setImage(buttonImages[0], for: .normal)
button2.setImage(buttonImages[1], for: .normal)
button3.setImage(buttonImages[2], for: .normal)
button4.setImage(buttonImages[3], for: .normal)
//self.setupFirstSelection()
}

How to change button image size when button is resized?

I'm trying to set the image size for a button to match the size of the button. To get the actual size of the button, I do this in the layoutSubviews() method. But I ran into the following problem.
Calling self.setImage(imagePerson, for: .normal) causes layoutSubviews() to be called again and recursion occurs.
class CustomButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
self.setTitle("", for: .normal)
self.tintColor = .white
self.backgroundColor = .lightGray.withAlphaComponent(0.5)
}
override func layoutSubviews() {
super.layoutSubviews()
self.layer.cornerRadius = self.frame.size.height/2
let size = self.frame.height * 0.5
let config = UIImage.SymbolConfiguration(pointSize: size)
let imagePerson = UIImage(systemName: "person.fill",
withConfiguration: config)
let imageSafary = UIImage(systemName: "safari",
withConfiguration: config)
switch restorationIdentifier {
case "1": self.setImage(imagePerson, for: .normal)
case "2": self.setImage(imageSafary, for: .normal)
default: break
}
}
}
You can use a property to track the change in the size of the button.
Something like this:
class CustomButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
self.setTitle("", for: .normal)
self.tintColor = .white
self.backgroundColor = .lightGray.withAlphaComponent(0.5)
}
// to track the size change
var curWidth: CGFloat = 0
override func layoutSubviews() {
super.layoutSubviews()
// only do this if the size has changed
if curWidth != bounds.width {
curWidth = bounds.width
self.layer.cornerRadius = self.frame.size.height/2
let size = self.frame.height * 0.5
let config = UIImage.SymbolConfiguration(pointSize: size)
let imagePerson = UIImage(systemName: "person.fill",
withConfiguration: config)
let imageSafary = UIImage(systemName: "safari",
withConfiguration: config)
switch restorationIdentifier {
case "1": self.setImage(imagePerson, for: .normal)
case "2": self.setImage(imageSafary, for: .normal)
default: break
}
}
}
}

On Change Function In Class Swift

I created a DropDownMenu class, but I need to know when the value changed in the ViewController. Like a UIScrollView didScroll, but for the value change in my class.
func scrollViewDidScroll(_ scrollView: UIScrollView)
I need something like that, but for the class!
Here is the class...
class DropDownMenu: UIStackView {
var options: [String]! = [] // Labels for all of the options
var titleButton: UIButton! = UIButton() // The Main Title Button
var target: UIViewController! // The target to get the main view. Maybe remove and automatically do it later
var textColor: UIColor! = UIColor.black // The Color of the text of the options
var bgColor: UIColor! = UIColor.clear
var borderWidth: CGFloat! = 0.0
var borderColor: CGColor! = UIColor.black.cgColor
var uiBorderColor: UIColor? = nil
var cornerRadius: CGFloat! = 0.0
var font: UIFont! = UIFont.systemFont(ofSize: 18)
var images: [UIImage]? = nil
var imageInsets: [UIEdgeInsets]? = nil
var imageInset: UIEdgeInsets? = nil
var value: String! {
get {
return currentSelected
}
set {
currentSelected = newValue
}
}
private var currentSelected: String! = ""
init(options: [String]) {
self.options = options
super.init(frame: CGRect.zero)
self.translatesAutoresizingMaskIntoConstraints = false
self.axis = .vertical
}
init(titleButton: UIButton) {
self.titleButton = titleButton
super.init(frame: CGRect.zero)
self.translatesAutoresizingMaskIntoConstraints = false
self.axis = .vertical
}
func createDropDownMenu() {
currentSelected = titleButton.titleLabel?.text
let mainFrame = titleButton.frame
print("Frame: \(mainFrame)")
print("StackView frame: \(self.frame), axis: \(self.axis)")
if uiBorderColor != nil {
borderColor = uiBorderColor!.cgColor
}
self.widthAnchor.constraint(equalToConstant: mainFrame.width).isActive = true
self.leftAnchor.constraint(equalTo: titleButton.leftAnchor).isActive = true
self.topAnchor.constraint(equalTo: titleButton.bottomAnchor, constant: self.spacing).isActive = true
var y: CGFloat = 0
var place = 0
for title in self.options {
let button = UIButton(frame: CGRect(x: 0, y: y, width: mainFrame.width, height: mainFrame.height))
button.setTitle(title, for: .normal)
button.setTitleColor(textColor, for: .normal)
button.backgroundColor = bgColor
button.addTarget(self, action: #selector(dropDownOptionClicked(_:)), for: .touchUpInside)
button.layer.cornerRadius = cornerRadius
button.layer.borderWidth = borderWidth
button.layer.borderColor = borderColor
button.titleLabel?.font = font
if images != nil {
button.setBackgroundImage(images![place], for: .normal)
if imageInsets != nil {
button.imageEdgeInsets = imageInsets![place]
} else if imageInsets == nil && imageInset != nil{
button.imageEdgeInsets = imageInset!
} else {
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
}
print("Button: \(button), Title: \(String(describing: button.titleLabel?.text)), Target: \(button.allTargets)")
button.isHidden = true
button.alpha = 0
self.addArrangedSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
button.widthAnchor.constraint(equalToConstant: mainFrame.width).isActive = true
button.heightAnchor.constraint(equalToConstant: mainFrame.height).isActive = true
print("Subviews: \(self.arrangedSubviews)")
y += mainFrame.height
place += 1
print("y: \(y)")
}
}
#objc func openDropDown(_ sender: UIButton) {
print("Open DropDownMenu")
self.arrangedSubviews.forEach { (button) in
UIView.animate(withDuration: 0.7) {
button.isHidden = !button.isHidden
button.alpha = button.alpha == 0 ? 1 : 0
self.target.view.layoutIfNeeded()
}
}
}
#objc private func dropDownOptionClicked(_ sender: UIButton) {
let text = sender.titleLabel?.text
print(text as Any)
currentSelected = text
print("Value: \(String(describing: value))")
titleButton.setTitle(text, for: .normal)
openDropDown(sender)
}
init() {
super.init(frame: CGRect.zero)
self.translatesAutoresizingMaskIntoConstraints = false
self.axis = .vertical
}
required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Here is the creation in ViewController...
let titleButton = UIButton(frame: CGRect(x: 50, y: 290, width: 100, height: 40))
titleButton.backgroundColor = UIColor.white
titleButton.setTitle("Grade", for: .normal)
titleButton.setTitleColor(UIColor.black, for: .normal)
titleButton.layer.borderWidth = 2
titleButton.layer.cornerRadius = 10
let dp = DropDownMenu(options: ["1", "Freshman", "Sophomore", "Junior", "Senior", "College"])
dp.titleButton = titleButton
dp.target = self
dp.borderWidth = 2
dp.spacing = 5
dp.cornerRadius = 10
dp.bgColor = UIColor.white
titleButton.addTarget(dp, action: #selector(dp.openDropDown(_:)), for: .touchUpInside)
infoBox.addSubview(titleButton)
infoBox.addSubview(dp)
dp.createDropDownMenu()
The class works as expected.
I really need help on this. No answer is a bad one. This is all of my code.
You usually do that with a delegate:
class DropDownMenu: UIStackView {
weak var delegate: DropDownMenuDelegate?
var value: String! {
get {
return currentSelected
}
set {
if currentSelected != newValue {
currentSelected = newValue
self.delegate?.valueDidChange(self)
}
}
}
}
protocol DropDownMenuDelegate: class {
func valueDidChange(_ menu: DropDownMenu)
}
Then in your View Controller:
let dp = DropDownMenu(options: ["1", "Freshman", "Sophomore", "Junior", "Senior", "College"])
dp.delegate = self
(typing this in the blind as I'm away from Xcode so there may be syntax errors)

Edit- How can I add that when the answer is wrong it will turn red and green in the correct answer? Swift 4.2

Creates a quiz game
How can I add that when the answer is incorrect, the incorrect answer will turn red and the correct answer will turn green at the same time?
How can I make the colors disappear when the new question comes? I have it that when you press an answer, a new question will come right after that
EDIT: This code is working fine.
#IBOutlet var options: [UIButton]!
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var progressView: UIView!
var allQuestions = QuestionBank()
var Number: Int = 0
var selectedAnswer: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
oppdatertekst()
options.forEach {
$0.layer.cornerRadius = 20
$0.backgroundColor = UIColor.orange
$0.setTitleColor(UIColor.black, for: .normal)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func answerPressed(_ sender: UIButton) {
feedback()
if sender.tag == selectedAnswer {
sender.backgroundColor = UIColor.green
let riktig = NSLocalizedString("Quiz.riktig", comment: "")
ProgressHUD.showSuccess(riktig)
} else if let correctOption = options.first(where: { $0.tag == selectedAnswer }) {
let feilnr = NSLocalizedString("Quiz.feilnr", comment: "")
ProgressHUD.showError("\(feilnr)\(selectedAnswer)")
correctOption.backgroundColor = UIColor.green
sender.backgroundColor = UIColor.red
}
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.Number += 1
self.oppdatertekst()
}
}
func oppdaterSpm() {
if Number <= allQuestions.list.count - 1{
questionLabel.text = allQuestions.list[Number].question
options.forEach {
$0.backgroundColor = .white
}
options[0].setTitle(allQuestions.list[Number].optionA, for: .normal)
options[1].setTitle(allQuestions.list[Number].optionB, for: .normal)
options[2].setTitle(allQuestions.list[Number].optionC, for: .normal)
options[3].setTitle(allQuestions.list[Number].optionD, for: .normal)
selectedAnswer = allQuestions.list[Number].correctAnswer
} else {
let alert....
}
}
Instead of having four IBOutlets use IBOutletCollection and connect these four buttons to this collection.
In answerPressed method if the correct answer is selected change clicked button color to green. If the wrong answer is selected change selected answer color to red, then get the correct answer button from the collection and change its color to green. After 5 seconds reload next question.
class ViewController: UIViewController {
#IBOutlet var options: [UIButton]!
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var progressView: UIView!
var allQuestions = QuestionBank()
var Number: Int = 0
var selectedAnswer: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
oppdatertekst()
options.forEach {
$0.layer.cornerRadius = 20
$0.backgroundColor = UIColor.orange
$0.setTitleColor(UIColor.black, for: .normal)
}
}
#IBAction func answerPressed(_ sender: UIButton) {
feedback()
if sender.tag == selectedAnswer {
sender.backgroundColor = UIColor.green
let riktig = NSLocalizedString("Quiz.riktig", comment: "")
ProgressHUD.showSuccess(riktig)
} else if let correctOption = options.first(where: { $0.tag == selectedAnswer }) {
let feilnr = NSLocalizedString("Quiz.feilnr", comment: "")
ProgressHUD.showError("\(feilnr)\(selectedAnswer)")
correctOption.backgroundColor = UIColor.green
sender.backgroundColor = UIColor.red
}
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
Number += 1
oppdatertekst()
}
}
}
Change all buttons color in oppdaterSpm method
func oppdaterSpm() {
if Number <= allQuestions.list.count - 1{
questionLabel.text = allQuestions.list[Number].question
options.forEach {
$0.backgroundColor = .white
}
options[0].setTitle(allQuestions.list[Number].optionA, for: .normal)
options[1].setTitle(allQuestions.list[Number].optionB, for: .normal)
options[2].setTitle(allQuestions.list[Number].optionC, for: .normal)
options[3].setTitle(allQuestions.list[Number].optionD, for: .normal)
selectedAnswer = allQuestions.list[Number].correctAnswer
} else {
let alert....
}
}
You have to write UIButton changes in common method. Call it anywhere.
When New Question Comes:
func whenNewQuestionComes() {
optionA.layer.cornerRadius = 20
optionA.backgroundColor = UIColor.orange
optionA.setTitleColor(UIColor.black, for: .normal)
optionB.layer.cornerRadius = 20
optionB.backgroundColor = UIColor.orange
optionB.setTitleColor(UIColor.black, for: .normal)
optionC.layer.cornerRadius = 20
optionC.backgroundColor = UIColor.orange
optionC.setTitleColor(UIColor.black, for: .normal)
optionD.layer.cornerRadius = 20
optionD.backgroundColor = UIColor.orange
optionD.setTitleColor(UIColor.black, for: .normal)
}
Show Green and Red
#IBAction func answerPressed(_ sender: UIButton) {
feedback()
optionA.backgroundColor = UIColor.red
optionB.backgroundColor = UIColor.red
optionC.backgroundColor = UIColor.red
optionD.backgroundColor = UIColor.red
if sender.tag == selectedAnswer {
sender.backgroundColor = UIColor.green
let riktig = NSLocalizedString("Quiz.riktig", comment: "")
ProgressHUD.showSuccess(riktig)
}
/*
else if let correctOption = options.first(where: { $0.tag == selectedAnswer }) {
let feilnr = NSLocalizedString("Quiz.feilnr", comment: "")
ProgressHUD.showError("\(feilnr)\(selectedAnswer)")
correctOption.backgroundColor = UIColor.green
sender.backgroundColor = UIColor.red
}
*/
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.Number += 1
self.oppdatertekst()
}
}