I want to hide a dynamic button with Swift 3 but I can't get it done. I just started with Swift but have some time pressure considering development of an app.
After pressing ButtonGen1 I want to hide this button and view 2 other buttons namely ButtonGen2_1 and ButtonGen2_2.
Using Google I tried several things. For example the following:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
createButtonGen1()
buttonGen1?.removeFromSuperview
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func createButtonGen1 ()
{
let buttonGen1 = UIButton(frame: CGRect(x:100, y: 100, width: 100, height: 50))
buttonGen1.setTitle("Is the original visit to this outlet to Eat or Drink?", for: .normal)
buttonGen1.setTitleColor(UIColor.orange, for: .normal)
buttonGen1.addTarget(self, action: #selector(buttonActionGen1), for: .touchUpInside)
self.view.addSubview(buttonGen1)
}
func createButtonGen2_1 ()
{
let buttonGen2_1 = UIButton(frame: CGRect(x:50, y: 100, width: 100, height: 150))
buttonGen2_1.setTitle("Is the name Restaurant?", for: .normal)
buttonGen2_1.setTitleColor(UIColor.blue, for: .normal)
buttonGen2_1.addTarget(self, action: #selector(buttonAction2_1), for: .touchUpInside)
self.view.addSubview(buttonGen2_1)
}
func createButtonGen2_2 ()
{
let buttonGen2_2 = UIButton(frame: CGRect(x:150, y: 100, width: 100, height: 150))
buttonGen2_2.setTitle("Is the name Restaurant?", for: .normal)
buttonGen2_2.setTitleColor(UIColor.red, for: .normal)
buttonGen2_2.addTarget(self, action: #selector(buttonAction2_2), for: .touchUpInside)
self.view.addSubview(buttonGen2_2)
}
func buttonActionGen1(sender: UIButton!) {
// ----> HOW TO HIDE BUTTON buttonGen1
buttonGen1.hidden = true
createButtonGen2_1 ()
createButtonGen2_2 ()
}
func buttonAction2_1(sender: UIButton!)
{
print("Button 2_1 tapped")
}
func buttonAction2_2(sender: UIButton!)
{
print("Button 2_2 tapped")
}
HOW TO HIDE BUTTON buttonGen1 ?!?!?!?
Your help is much appreciated!!!
Related
I would like to extend the SwiftUI.Button so that i can add a type prop and have that type change to different types of my theme buttons. But I am new to Swift and I can't figure out how to have my label and action props be generic.
In other words if i do this
import SwiftUI
struct Button: View {
var type: String = ""
var action = {}
var label = {
Text("Button")
}
var body: some View {
ZStack(content: {
SwiftUI.Button(action: action, label: label)
})
}
}
it limits the closure to only allow for label to return text()
how can this be done
also any suggestions on how i should to alter the "alterations" done to the button based on the type.
NOTE:
someone downvoted this because it is similar to button style query from another user however it is not.
that solution is for simply adding pre-made styles to the default SwiftUI.button struct and that's not my goal.
I'm attempting to extend SwiftUI.Button with a type property that can be passed and will set the styling based that input.
Although they share the same result they are not accomplishing the same goal. My solution will offer a dynamically styled component which can be used throughout the project. without the need of trailing .buttonStyle(BlueButtonStyle())
As I see you are trying re create apple Button, You can do like this, and then do your customisation in body:
struct Button<Content: View>: View {
let action: () -> Void
let label: () -> Content
init(action: #escaping () -> Void, #ViewBuilder label: #escaping () -> Content) {
self.action = action
self.label = label
}
init(action: #escaping () -> Void, title: String) where Content == Text {
self.init(action: action, label: { Text(title) })
}
var body: some View { label().onTapGesture { action() } }
}
use case:
Button(action: { print("hello") }, label: { Text("Button") })
Button(action: { print("hello") }, title: "Button")
The Conclusion of what swiftPunk put is the following.
struct Button<Content: View>: View {
let type: button_styles
let action: () -> Void
let label: () -> Content
enum button_styles {
case filled
case outlined
case plain
}
init(type: button_styles, action: #escaping () -> Void, #ViewBuilder label: #escaping () -> Content ) {
self.type = type
self.action = action
self.label = label
}
init(type: button_styles, action: #escaping () -> Void, title: String) where Content == Text {
self.init(type: type, action: action, label: { Text(title) })
}
init(action: #escaping () -> Void, title: String) where Content == Text {
self.init(type: .plain, action: action, label: { Text(title) })
}
init(action: #escaping () -> Void, #ViewBuilder label: #escaping () -> Content) {
self.init(type: .plain, action: action, label: label)
}
var body: some View {
switch type {
case .filled:
SwiftUI.Button(action: self.action, label: self.label).buttonStyle(FilledButtonStyle())
case .outlined:
SwiftUI.Button(action: self.action, label: self.label).buttonStyle(OutlinedButtonStyle())
case .plain:
SwiftUI.Button(action: self.action, label: self.label).buttonStyle(PlainButtonStyle())
}
}
}
struct FilledButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.font(.headline)
.frame(maxWidth: 108, maxHeight: 34, alignment: .center)
.contentShape(Rectangle())
.foregroundColor(configuration.isPressed ? Color.white.opacity(0.5) : Color.white)
.background(configuration.isPressed ? Color("Red").opacity(0.5) : Color("Red"))
.cornerRadius(20)
}
}
struct OutlinedButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.font(.headline)
.frame(maxWidth: 108, maxHeight: 34, alignment: .center)
.foregroundColor(Color("Grey"))
.background(Color.white.opacity(0))
.overlay(RoundedRectangle(cornerRadius:10).stroke(Color("Grey"), lineWidth: 2))
}
}
struct PlainButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.font(.headline)
.frame(maxWidth: 108, maxHeight: 34, alignment: .center)
.contentShape(Rectangle())
.foregroundColor(configuration.isPressed ? Color.white.opacity(0.5) : Color("Grey"))
}
}
which will allow you to use the Button Struct like:
Button(type: .outlined, action: { print("pressed") }, title: "Button")
or
Button(action: { print("pressed") }, title: "Button")
or
Button(action: addItem, label: {
Label("Add Item", systemImage: "plus")
})
I am working with gestures first time here. Please let me know if my approach is wrong or any better solution.
I am trying to delete the collectionView Cell on swiping Left just like UITableview delete function. Deleting works fine. Now what I want is, Once I swipe the cell and tap anywhere on COllectionView it should swipe back to its original position(same like tableview delete row functionality)
I am using/trying this code
Updated viewDidLoad and tapped event
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(tapped(_:)))
self.view.addGestureRecognizer(tap)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let Cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as! CustomCell
Cell.backgroundColor = UIColor.white
let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(delete(sender:)))
leftSwipe.direction = UISwipeGestureRecognizerDirection.left
Cell.addGestureRecognizer(leftSwipe)
let tap = UITapGestureRecognizer(target: self, action: #selector(tapped(_:)))
Cell.addGestureRecognizer(tap)
Cell.deleteButton.addTarget(self, action: #selector(DeleteCell(sender:)), for: .touchUpInside)
}
func tapped(_ recognizer: UITapGestureRecognizer) {
// self.collectionView.performBatchUpdates({
//self.collectionView.reloadSections(NSIndexSet(index: 0) as IndexSet)
//}, completion: nil)
let point = recognizer.location(in: collectionView)
let indexPath = collectionView.indexPathForItem(at: point)
let cell = self.collectionView.cellForItem(at: indexPath!)
UIView.animate(withDuration: 0.4) {
cell?.contentView.frame = CGRect(x: 0, y: 0, width: (cell?.contentView.frame.width)!, height: (cell?.contentView.frame.height)!)
}
}
func delete(sender: UISwipeGestureRecognizer){
let cell = sender.view as! CustomCell
UIView.animate(withDuration: 0.4) {
cell.contentView.frame = CGRect(x: -90, y: 0, width: cell.contentView.frame.width, height: cell.contentView.frame.height)
}
}
func DeleteCell(sender : AnyObject){
let cell = sender.superview as! CustomCell
let i = self.collectionView.indexPath(for: cell)!.item
let indexpath = self.collectionView.indexPath(for: cell)
let array : NSMutableArray = []
self.collectionView.performBatchUpdates({
self.userArray.remove(at: i)
array.add(indexpath!)
self.collectionView.deleteItems(at:array as! [IndexPath])
}, completion: nil)
}
class CustomCell: UICollectionViewCell {
let deleteButton: UIButton = {
let deleteBtn = UIButton()
deleteBtn.setImage(UIImage(named: "red"), for: .normal)
deleteBtn.contentMode = .scaleAspectFit
return deleteBtn
}()
}
So here I am able to set the cell's position back to original by self.collectionView.performBatchUpdates but its not smooth animation. I tried using
UIView.animate(withDuration: 0.4) {
cell.contentView.frame = CGRect(x: 0, y: 0, width: cell.contentView.frame.width, height: cell.contentView.frame.height)
}
but it works only if swiped cell tapped, not any other cell or anywhere else. Any suggestions would be helpful!!
Right now you are accessing your cell from within itself. The reason it only works to tap on the cell you just swiped is because that is the only cell with that specific instance of UITapGestureRecognizer. To fix this, you should add that tap gesture recognizer to your whole view. Try adding this to your viewDidLoad() method:
let tap = UITapGestureRecognizer(target: self, action: #selector(tapped(_:)))
self.view.addGestureRecognizer(tap)
Finally, got the solution.
Here is the demo project I found - CollectionViewSlideLeft
Hope it will help someone like me. :)
I want to hide the back button and set a title.
I'm using the following code:
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Einstellungen"
navigationItem.hidesBackButton = true }
But the title isn't shown and the back button is still there but if I touch it nothing happens. Can anybody help me please?
I found a solution on my own.
If I'm setting the title and the hidesBackButton from my previous ViewController everything works fine.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destinationVC = segue.destination as? ViewControllerFirstSettings {
destinationVC.navigationItem.hidesBackButton = true
destinationVC.navigationItem.title = "Einstellungen"
}
}
This code may help :
// MARK: - CUSTOM METHODS
func createNavBar() {
let leftNavigationButton = UIButton()
leftNavigationButton.setImage(UIImage(named: "ic_back.png"), forState: .Normal)
leftNavigationButton.frame = CGRectMake(10, 10, 20, 15)
leftNavigationButton.addTarget(self, action: "onBackButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
let customBarItem = UIBarButtonItem(customView: leftNavigationButton)
self.navigationItem.leftBarButtonItem = customBarItem;
//set TitleAppIcon
let GR = UITapGestureRecognizer(target: self, action: Selector("headerLogoTapAction:"))
let imageView = UIImageView(frame: CGRect(x: 90, y: 0, width: ((UIScreen.mainScreen().bounds.width)/3), height: 40))
imageView.addGestureRecognizer(GR)
imageView.userInteractionEnabled = true
navigationItem.titleView = imageView
}
I am experimenting not using storyboards and just writing the UI in code. I have the button attributes, i added to the subview to the viewDidLoad and also set up the constraints. I should be seeing a button in the middle of the screen.
class ViewController: UIViewController {
var setupButton: UIButton = {
let button = UIButton(type: .system)
button.backgroundColor = UIColor(r: 80, g: 101, b: 161, a: 256)
button.setTitle("Button", for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
view.addSubview(setupButton)
coolButton()
}
func coolButton() {
setupButton.centerXAnchor.constraint(equalTo: view.centerXAnchor)
setupButton.centerYAnchor.constraint(equalTo: view.centerYAnchor)
setupButton.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -24)
setupButton.heightAnchor.constraint(equalToConstant: 150)
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension UIColor {
convenience init(r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) {
self.init(red: r/255, green: g/255, blue: b/255, alpha: a/255)
}
}
From NSLayoutConstraint docs:
Note that only active constraints affect the calculated layout.
For newly created constraints, the active property is NO by default.
You just have to set the isActive property to true for your constraints.
setupButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
setupButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
setupButton.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -24).isActive = true
setupButton.heightAnchor.constraint(equalToConstant: 150).isActive = true
I have written a class file to create a topBar for my app, I also add in buttons to the top bar after adding target to the buttons added, the same is not triggered
the line menuButton.addTarget(self, action: #selector(showMenu), for: .touchUpInside) does not trigger the function showMenu
I create a TN object(from class TopNav) in the main view file and add it to the view, but the menu button does not trigger the tap
import Foundation
import UIKit
class TopNav{
var topView: UIView = UIView()
var menuButton: UIButton = UIButton()
#objc func showMenu(sender: UIButton!) {
print("show Menu")
}
func position(){
let bounds = UIScreen.main.bounds
let width = bounds.size.width
topView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: width, height: 60.0))
topView.backgroundColor = UIColor.init(colorLiteralRed: 66/255, green: 74/255, blue: 87/255, alpha: 1.0)
menuButton = UIButton(frame: CGRect(x: (width-40), y: 20.0, width: 30.0, height: 30.0))
menuButton.setBackgroundImage( UIImage(named:"menu"), for: .normal)
menuButton.setTitle("", for: UIControlState.normal)
menuButton.addTarget(self, action: #selector(showMenu), for: .touchUpInside)
topView.addSubview(menuButton)
}
}
You may try this.
class TopNav {
func position() {
...
menuButton.addTarget(self, action: #selector(TopNav.showMenu), for: .touchUpInside)
...
}
func showMenu() {
//your code
}
}