I want put Ad banner in my app.
I don't have the storyboard, I 've 4 ViewCOntroller, in the main I've this, can someone help me please?
In AppDelegate: GADMobileAds.configure(withApplicationID: "...")
import UIKit
import Firebase
import GoogleMobileAds
class ViewController: UIViewController {
var window: UIWindow?
override func viewDidLoad(){
super.viewDidLoad()
self.title="Andrea Damante Quiz"
self.view.backgroundColor=UIColor(patternImage: UIImage(named: "andrea15.jpeg")!)
let backgroundImage = UIImageView(frame: UIScreen.main.bounds)
backgroundImage.image = UIImage(named: "andrea15.jpeg")
backgroundImage.contentMode = UIViewContentMode.scaleAspectFill
self.view.insertSubview(backgroundImage, at: 0)
setupViews()
}
#objc func btnGetStartedAction() {
let v=QuizVC()
self.navigationController?.pushViewController(v, animated: true)
}
func setupViews() {
self.view.addSubview(lblTitle)
lblTitle.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 150).isActive=true
lblTitle.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive=true
lblTitle.widthAnchor.constraint(equalToConstant: 250).isActive=true
lblTitle.heightAnchor.constraint(equalToConstant: 80).isActive=true
self.view.addSubview(btnGetStarted)
btnGetStarted.heightAnchor.constraint(equalToConstant: 50).isActive=true
btnGetStarted.widthAnchor.constraint(equalToConstant: 150).isActive=true
btnGetStarted.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive=true
btnGetStarted.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: 0).isActive=true
}
let lblTitle: UILabel = {
let lbl=UILabel()
lbl.text="Quiz"
lbl.textColor=UIColor.darkGray
lbl.textAlignment = .center
lbl.font = UIFont.systemFont(ofSize: 46)
lbl.numberOfLines=2
lbl.translatesAutoresizingMaskIntoConstraints=false
return lbl
}()
let btnGetStarted: UIButton = {
let btn=UIButton()
btn.setTitle("Via!", for: .normal)
btn.setTitleColor(UIColor.white, for: .normal)
btn.backgroundColor=UIColor.orange
btn.layer.cornerRadius=5
btn.layer.masksToBounds=true
btn.translatesAutoresizingMaskIntoConstraints=false
btn.addTarget(self, action: #selector(btnGetStartedAction), for: .touchUpInside)
return btn
}()
}
You need to declare and set up a GADBannerView and add it to your view controller. You won't need a UIWindow. Use this code:
import GoogleMobileAds
import UIKit
class ViewController: UIViewController {
var bannerView: GADBannerView!
override func viewDidLoad() {
super.viewDidLoad()
// In this case, we instantiate the banner with desired ad size.
bannerView = GADBannerView(adSize: kGADAdSizeBanner)
addBannerViewToView(bannerView)
}
func addBannerViewToView(_ bannerView: GADBannerView) {
bannerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(bannerView)
view.addConstraints(
[NSLayoutConstraint(item: bannerView,
attribute: .bottom,
relatedBy: .equal,
toItem: bottomLayoutGuide,
attribute: .top,
multiplier: 1,
constant: 0),
NSLayoutConstraint(item: bannerView,
attribute: .centerX,
relatedBy: .equal,
toItem: view,
attribute: .centerX,
multiplier: 1,
constant: 0)
])
}
}
which was taken from here: https://developers.google.com/admob/ios/banner.
Also make sure to set the ad unit ID and the delegate:
override func viewDidLoad() {
super.viewDidLoad()
...
bannerView.adUnitID = "ca-app-pub-3940256099942544/2934735716"
bannerView.rootViewController = self
bannerView.load(GADRequest())
}
But again, you'll everything you need in the official guide.
Related
I am trying to set up the a navigation bar and a WKWebview in my app, the webview is present but i am not able to see the navigation bar is not visible. What am i doing wrong?
I edited my code now it functions well this is the problem remaining.
This is my code
class MyController:UIViewController, WKNavigationDelegate{
var webView: WKWebView!
#IBOutlet weak var barView: UIView!
required init(coder aDecoder: NSCoder) {
self.webView = WKWebView(frame: CGRect.zero)
super.init(coder: aDecoder)!
self.webView.navigationDelegate = self
}
override func viewDidLoad() {
super.viewDidLoad()
barView.frame = CGRect(x:0, y: 0, width: view.frame.width, height: 40)
view.insertSubview(webView, belowSubview: barView)
webView.translatesAutoresizingMaskIntoConstraints = false
let height = NSLayoutConstraint(item: webView, attribute: .height, relatedBy: .equal, toItem: view, attribute: .height, multiplier: 1, constant: 0)
let width = NSLayoutConstraint(item: webView, attribute: .width, relatedBy: .equal, toItem: view, attribute: .width, multiplier: 1, constant: 0)
view.addConstraints([height, width])
if((UserDefaults.standard.object(forKey:"language")as? String ?? "") == "en"){
let url = URL(string: "myurl")!
webView.load(URLRequest(url: url))
}
else{
let url = URL(string: "https://myurl")!
webView.load(URLRequest(url: url))
}
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
barView.frame = CGRect(x:0, y: 0, width: size.width, height: 40)
}
override func viewWillAppear(_ animated: Bool) {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func btnSideMenuActn(_ sender: UIButton) {
self.pushViewControl(ViewControl:"SideMenuController")
}
}
I'm trying to add views(or buttons) to UIStackView dynamically.
At first, the UIStackView has no arranged views (vertically), and
after getting from some http response, several views(buttons) are added to UIStackView.
UIStackView is also autolayout to hold a specific area.
I've tried to find dynamic adding example, but failed.
Anyone can show me the examples of adding view onto UIStackView dynamically?
It may help you. Please follow this points:
Add UIScrollView to your UIViewController in storyboard or XIB.
Initiate an NSMutableArray name it arrViews gets server response and adds view in the array.
Initialise UIStackViewpass arrView array in the init method.
After that UIStackView will be added subview of UIScrollView.
Add constraint programmatically to UIStackView. That's it.
if let response = self.serverResponse {
if let body = response.responseBody {
if let view = body.views {
arrViews = createSubViews(view)
}
}
}
let stackView = UIStackView(arrangedSubviews: arrViews)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 16
stackView.distribution = .fill
self.scrollView.addSubview(stackView)
//constraints
let leading = NSLayoutConstraint(item: stackView, attribute: .leading, relatedBy: .equal, toItem: self.scrollView, attribute: .leading, multiplier: 1.0, constant: 0)
self.scrollView.addConstraint(leading)
let trailing = NSLayoutConstraint(item: stackView, attribute: .trailing, relatedBy: .equal, toItem: self.scrollView, attribute: .trailing, multiplier: 1.0, constant: 0)
self.scrollView.addConstraint(trailing)
let top = NSLayoutConstraint(item: stackView, attribute: .top, relatedBy: .equal, toItem: self.scrollView, attribute: .top, multiplier: 1.0, constant: 0)
self.scrollView.addConstraint(top)
let bottom = NSLayoutConstraint(item: stackView, attribute: .bottom, relatedBy: .equal, toItem: self.scrollView, attribute: .bottom, multiplier: 1.0, constant: 0)
self.scrollView.addConstraint(bottom)
let equalWidth = NSLayoutConstraint(item: stackView, attribute: .width, relatedBy: .equal, toItem: self.scrollView, attribute: .width, multiplier: 1.0, constant: 0)
self.scrollView.addConstraint(equalWidth)
leading.isActive = true
trailing.isActive = true
top.isActive = true
bottom.isActive = true
equalWidth.isActive = true
Hope it will help you. Happy coding :)
I use this code in one of my projects:
let baseFrame = CGRect(origin: .zero, size: CGSize(width: requiredWidth, height: partitionHeight))
for instrument in instruments {
let partitionView = PartitionOnDemand(instrument: instrument, mode: playbackMode, frame: baseFrame, referenceView: partitionsAnimator)
partitionsStackView.addArrangedSubview(partitionView)
let tab = InstrumentInfoTabContainer.instantiate(with: instrument) {
self.focus(on: instrument)
}
tabsStackView.addArrangedSubview(tab)
}
While trying with answers, I happend to find how to work it.
class ViewController: UIViewController {
#IBOutlet weak var stack: UIStackView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func onBtn_Create(_ sender: Any) {
createButton("new button ...")
}
#IBAction func onBtn_Delete(_ sender: Any) {
if let v = stack.arrangedSubviews.last {
stack.removeArrangedSubview(v)
v.removeFromSuperview()
}
}
func createButton(_ title: String) {
let button = UIButton()
button.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
button.backgroundColor = UIColor.blue
button.setTitle(title, for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
stack.addArrangedSubview(button)
}
#objc func buttonAction(sender: UIButton!) {
print("Button tapped")
}
}
And, I anchored to UIStackView, Trailing=0, Leading=0, Top=0, Bottom=8 to TextView.Top
The subviews inside it are intact without any constraints.
Thank you.
I have looked and tried every solution I could find online as to why my animations is not properly firing. DISCLOSURE: they work fine when put in viewDidAppear(). This question has been asked countless times but none of the solutions work. The results of the animations appear but not with the delay specified, they are instant. What I would like is to fade in a my requestRideButton in and out using either isHidden with UIView.transition or alpha with UIView.animate.
I would also like to move the button while it is fading. I have tried every combination of self.view.layoutIfNeeded() both in and out the animate closure with the constraint in and out. I have also tried it with self.view.superview?.layoutIfNeeded()
class RideRequestViewController: UIViewController, MKMapViewDelegate {
#IBOutlet weak var rideRequestBottomButtonConstraint: NSLayoutConstraint!
#IBOutlet weak var rideRequestButtonTopConstraint: NSLayoutConstraint!
// Views
#IBOutlet var mapView: MKMapView!
#IBOutlet var rideDetailsView: UIView!
#IBOutlet var requestRideButton: UIButton!
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Layout map view to fill screen
mapView.frame = view.bounds
// Apply corner radius and shadow styling to floating views
let cornerRadius: CGFloat = 5.0
inputContainerView.layoutCornerRadiusAndShadow(cornerRadius: cornerRadius)
originButton.layoutCornerRadiusMask(corners: [.topLeft, .topRight], cornerRadius: cornerRadius)
paymentButton.layoutCornerRadiusMask(corners: .bottomLeft, cornerRadius: cornerRadius)
priceButton.layoutCornerRadiusMask(corners: .bottomRight, cornerRadius: cornerRadius)
rideDetailsView.layoutCornerRadiusAndShadow(cornerRadius: cornerRadius)
pilotView.layoutCornerRadiusMask(corners: [.topLeft, .bottomLeft], cornerRadius: cornerRadius)
vehicleView.layoutCornerRadiusMask(corners: [.topRight, .bottomRight], cornerRadius: cornerRadius)
requestRideButton.layoutCornerRadiusAndShadow(cornerRadius: cornerRadius)
}
override func viewDidLoad() {
ref = Database.database().reference()
}
func animate() {
self.rideRequestButtonTopConstraint.constant = -44
UIView.animate(withDuration: 1) {
self.view.layoutIfNeeded()
}
}
#IBAction
private func handleRequestRideButtonTapped() {
switch rideRequestState {
case .none:
// Update to requesting state
rideRequestState = .requesting
// Perform payment request
paymentContext.requestPayment()
case .requesting:
// Do nothing
// Show button
break
case .active:
// Complete the ride
completeActiveRide()
}
}
private func reloadRequestRideButton() {
guard originPlacemark != nil && destinationPlacemark != nil && paymentContext.selectedPaymentMethod != nil else {
// Show disabled state
requestRideButton.backgroundColor = .riderGrayColor
requestRideButton.setTitle("CONFIRM DELIVERY", for: .normal)
requestRideButton.setTitleColor(.black, for: .normal)
requestRideButton.setImage(nil, for: .normal)
requestRideButton.isEnabled = false
return
}
animate() // <--- view just disappears instantly instead
switch rideRequestState {
case .none:
// Show enabled state
requestRideButton.backgroundColor = .riderYellowColor
requestRideButton.setTitle("CONFIRM DELIVERY", for: .normal)
requestRideButton.setTitleColor(.black, for: .normal)
requestRideButton.setImage(nil, for: .normal)
requestRideButton.isEnabled = true
case .requesting:
// Show loading state
requestRideButton.backgroundColor = .riderYellowColor
requestRideButton.setTitle("...", for: .normal)
requestRideButton.setTitleColor(.white, for: .normal)
requestRideButton.setImage(nil, for: .normal)
requestRideButton.isEnabled = false
case .active:
// Show completion state
requestRideButton.backgroundColor = .white
requestRideButton.setTitle("Complete Ride", for: .normal)
requestRideButton.setTitleColor(.riderDarkBlueColor, for: .normal)
requestRideButton.setImage(nil, for: .normal)
requestRideButton.isEnabled = true
}
}
Changes to views to be animated should be inside the animate block.
func animate() {
UIView.animate(withDuration: 1) {
self.rideRequestButtonTopConstraint.constant = -44
self.view.layoutIfNeeded()
}
}
Changing the constraint in the line above will just update a value and move the view. It won't animate it
UPDATE
So based on looking at another answer and some additional research, The author of UIKit suggests that we update constraints and call layoutIfNeeded inside the animation block like above.
Here is the playground I used to test it
import UIKit
import PlaygroundSupport
class ViewController: UIViewController {
let movableView = UIView()
var topConstraint: NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
view.addSubview(button)
button.setTitle("Animate", for: .normal)
button.addTarget(self, action: #selector(animate), for: .touchUpInside)
view.addSubview(movableView)
movableView.backgroundColor = .red
movableView.translatesAutoresizingMaskIntoConstraints = false
topConstraint = NSLayoutConstraint(item: movableView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: 100)
topConstraint?.isActive = true
NSLayoutConstraint(item: movableView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: movableView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 100).isActive = true
NSLayoutConstraint(item: movableView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 100).isActive = true
}
#objc func animate() {
UIView.animate(withDuration: 4.0, animations: {
self.topConstraint?.constant = -100
self.view.layoutIfNeeded()
})
}
}
let vc = ViewController()
PlaygroundPage.current.liveView = vc.view
I have made a collection view programmatically but when set collectionView.delegate = self and collectionView.dataSource = self I get a nil while unwrapping an optional. I don't know what I did wrong here.
class MainFeedViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate, UIViewControllerTransitioningDelegate, UIGestureRecognizerDelegate, MyCollectionCell {
let transition = CircularAnimation()
var collectionView: UICollectionView!
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapEdit(recognizer:)))
func MyCollectionCell() {
let vc = DescriptionViewController()
self.present(vc, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.isHidden = true
collectionView.delegate = self
collectionView.dataSource = self
view.backgroundColor = .white
UIApplication.shared.isStatusBarHidden = false
UIApplication.shared.statusBarStyle = .default
view.addSubview(Settings)
view.addSubview(topBar)
view.addSubview(separatorView)
view.addSubview(separatorView2)
Settings.translatesAutoresizingMaskIntoConstraints = false
Settings.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 15).isActive = true
Settings.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
Settings.widthAnchor.constraint(equalToConstant: 50).isActive = true
Settings.heightAnchor.constraint(equalToConstant: 50).isActive = true
separatorView.translatesAutoresizingMaskIntoConstraints = false
separatorView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 40).isActive = true
separatorView.heightAnchor.constraint(equalToConstant: 1).isActive = true
view.addConstraint(NSLayoutConstraint(item: separatorView, attribute: .left, relatedBy: .equal, toItem: Settings, attribute: .right, multiplier: 1, constant: 15))
view.addConstraint(NSLayoutConstraint(item: separatorView, attribute: .right, relatedBy: .equal, toItem: topBar, attribute: .right, multiplier: 1, constant: 0))
separatorView2.translatesAutoresizingMaskIntoConstraints = false
separatorView2.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 40).isActive = true
separatorView2.heightAnchor.constraint(equalToConstant: 1).isActive = true
view.addConstraint(NSLayoutConstraint(item: separatorView2, attribute: .right, relatedBy: .equal, toItem: Settings, attribute: .left, multiplier: 1, constant: -15))
view.addConstraint(NSLayoutConstraint(item: separatorView2, attribute: .left, relatedBy: .equal, toItem: topBar, attribute: .left, multiplier: 1, constant: 0))
topBar.translatesAutoresizingMaskIntoConstraints = false
topBar.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
topBar.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
topBar.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
view.addConstraint(NSLayoutConstraint(item: topBar, attribute: .bottom, relatedBy: .equal, toItem: separatorView, attribute: .top, multiplier: 1, constant: 0))
view.insertSubview(topBar, belowSubview: Settings)
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
let height = (view.frame.width - 16 - 16) * 9/16
layout.sectionInset = UIEdgeInsets(top: 80, left: 0, bottom: 0, right: 0)
layout.itemSize = CGSize(width: view.frame.width, height: height + 16 + 80)
collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
collectionView?.scrollIndicatorInsets = UIEdgeInsetsMake(80, 0, 0, 0)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(Cell.self, forCellWithReuseIdentifier: "cellId")
collectionView.backgroundColor = UIColor.clear
collectionView.addGestureRecognizer(tapGesture)
tapGesture.delegate = self
self.view.addSubview(collectionView)
view.insertSubview(collectionView, belowSubview: topBar)
}
let Settings : UIButton = {
let btn = UIButton()
btn.setTitle("Clotho", for: .normal)
btn.setTitleColor(.white, for: .normal)
btn.layer.cornerRadius = 25
btn.backgroundColor = UIColor.rgb(displayP3Red: 255, green: 165, blue: 0)
btn.titleLabel?.font = UIFont(name: "Pacifico-Regular", size: 16)
btn.addTarget(self, action:#selector(settingsTab), for: .touchUpInside)
return btn
}()
let topBar: UIView = {
let bar = UIView()
bar.backgroundColor = .white
return bar
}()
let separatorView: UIView = {
let view = UIView()
view.backgroundColor = UIColor.rgb(displayP3Red: 211, green: 211, blue: 211)
return view
}()
let separatorView2: UIView = {
let view2 = UIView()
view2.backgroundColor = UIColor.rgb(displayP3Red: 211, green: 211, blue: 211)
return view2
}()
#objc func tapEdit(recognizer: UITapGestureRecognizer) {
if recognizer.state == UIGestureRecognizerState.ended {
let tapLocation = recognizer.location(in: self.collectionView)
if let tapIndexPath = self.collectionView.indexPathForItem(at: tapLocation) {
if (self.collectionView.cellForItem(at: tapIndexPath) as? Cell) != nil {
//do what you want to cell here
}
}
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! Cell
cell.Delegate = self
return cell
}
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
transition.transitionMode = .present
transition.startingPoint = Settings.center
transition.circleColor = Settings.backgroundColor!
return transition
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
transition.transitionMode = .dismiss
transition.startingPoint = Settings.center
transition.circleColor = Settings.backgroundColor!
return transition
}
#objc func settingsTab(){
let secondVC = SettingsViewController()
secondVC.transitioningDelegate = self
secondVC.modalPresentationStyle = UIModalPresentationStyle.custom
self.present(secondVC, animated: true, completion: nil)
}
}
I set a var Delegate: MyCollectionCell? in my cell with a protocol
import UIKit
protocol MyCollectionCell {
func MyCollectionCell()
}
class Cell: UICollectionViewCell {
var Delegate: MyCollectionCell?
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
let TapGesture = UITapGestureRecognizer(target: self, action: #selector(Cell.tapEdit(sender:)))
addGestureRecognizer(TapGesture)
TapGesture.delegate = MainFeedViewController()
}
//other setup code...
#objc func tapEdit(sender: UITapGestureRecognizer) {
Delegate?.MyCollectionCell()
}
You haven't actually created the collection view anywhere.
This line:
var collectionView: UICollectionView!
creates a variable ready to hold the collection view (and the ! character indicates you should populate the variable in the viewDidLoad method) but you don't actually create the instance of the UICollectionView and assign it to that variable.
So when you try to set the delegate and data source the collection view variable is still nil and hence you get an error.
You need to actually create the instance of a UICollectionView which is also going to involve creating an instance of a UICollectionViewLayout (or a subclass of it like UICollectionViewFlowLayout).
At the most basic level you should do something like this:
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: 100, height: 100)
collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: 500, height: 500), collectionViewLayout: layout)
although of course you should adjust the frame and the parameters of the layout to suit your usage requirements.
I am making UIImageView instances. I am having trouble making the UIImage clickable. I also would like the UIImage when clicked to send the user to a link on the Internet. How can I accomplish this? I have tried adding tap gestures and such but am having no luck. You can see this with the code that is commented out.
/File 1 Model File/
import Foundation
class Book : NSObject{
var thumbnailImageName: String?
var title : String?
var subTitle : String?
}
/File 2 Cell File/
import UIKit
class BookCell: BaseCell{
var book: Book?{
didSet{
thumbnailImageView.image = UIImage(named: (book?.thumbnailImageName)!)
titleLabel.text = book?.title
subtitleTextView.text = book?.subTitle
}
}
var thumbnailImageView: UIImageView = {
let imageView = UIImageView()
// let tapGesture = UITapGestureRecognizer(target: imageView, action: #selector(BookCell.tapBlurButton(_:)))
imageView.image = UIImage(named: "")
imageView.userInteractionEnabled = true
imageView.tag = 0
imageView.contentMode = .ScaleAspectFit
imageView.clipsToBounds = true
// imageView.addTarget(self, action: #selector(self.tapBlurButton(_:)), forControlEvents: .TouchUpInside)
// imageView.addGestureRecognizer(tapGestureRecognizer)
return imageView
}()
let userProfileImageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "Gary Vee Profile Pic 1")
imageView.layer.cornerRadius = 22
imageView.layer.masksToBounds = true
return imageView
}()
let separatorView: UIView = {
let view = UIView()
view.backgroundColor = UIColor(red: 230/255, green: 230/255, blue: 230/255, alpha: 1)
return view
}()
let titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "DailyVee 199"
label.userInteractionEnabled = false
return label
}()
let subtitleTextView: UITextView = {
let textView = UITextView()
textView.translatesAutoresizingMaskIntoConstraints = false
textView.text = "When a street hustler make 130 million"
textView.userInteractionEnabled = false
textView.textContainerInset = UIEdgeInsetsMake(0,-4,0,0)
textView.textColor = UIColor.darkGrayColor()
return textView
}()
let purchaseButton: UIButton = {
let button = UIButton(type: .System) // let preferred over var here
button.frame = CGRectMake(100, 100, 100, 50)
button.backgroundColor = UIColor.greenColor()
button.setTitle("Button", forState: UIControlState.Normal)
button.addTarget(button, action: #selector(Books.tapBlurButton(_:)), forControlEvents: .TouchUpInside)
return button
}()
override func setupViews(){
addSubview(thumbnailImageView)
addSubview(separatorView)
addSubview(userProfileImageView)
addSubview(titleLabel)
addSubview(subtitleTextView)
addSubview(purchaseButton)
addContraintsWithFormat("H:|-16-[v0]-16-|", views: thumbnailImageView)
addContraintsWithFormat("H:|-16-[v0(44)]", views: userProfileImageView)
//Vertical constraints
addContraintsWithFormat("V:|-16-[v0]-8-[v1(44)]-16-[v2(1)]|", views: thumbnailImageView, userProfileImageView, separatorView)
addContraintsWithFormat("H:|[v0]|", views: separatorView)
//top constraint
addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .Top, relatedBy: .Equal, toItem: thumbnailImageView, attribute:.Bottom, multiplier: 1, constant: 8))
//left constraint
addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .Left, relatedBy: .Equal, toItem: userProfileImageView, attribute:.Right, multiplier: 1, constant: 8))
//right constraint
addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .Right, relatedBy: .Equal, toItem: thumbnailImageView, attribute:.Right, multiplier: 1, constant: 0))
//height constraint
addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .Height, relatedBy: .Equal, toItem: self, attribute:.Height, multiplier: 0, constant: 20))
//top constraint
addConstraint(NSLayoutConstraint(item: subtitleTextView, attribute: .Top, relatedBy: .Equal, toItem: titleLabel, attribute:.Bottom, multiplier: 1, constant: 4))
//left constraint
addConstraint(NSLayoutConstraint(item: subtitleTextView, attribute: .Left, relatedBy: .Equal, toItem: userProfileImageView, attribute:.Right, multiplier: 1, constant: 8))
//right constraint
addConstraint(NSLayoutConstraint(item: subtitleTextView, attribute: .Right, relatedBy: .Equal, toItem: thumbnailImageView, attribute:.Right, multiplier: 1, constant: 0))
//height constraint
addConstraint(NSLayoutConstraint(item: subtitleTextView, attribute: .Height, relatedBy: .Equal, toItem: self, attribute:.Height, multiplier: 0, constant: 30))
}
}
/File 3 Class File/
class Books : UICollectionViewController, UICollectionViewDelegateFlowLayout {
var books: [Book] = {
var askGaryVee = Book()
askGaryVee.thumbnailImageName = "askgaryvee_book"
askGaryVee.title = "#ASKGARYVEE: ONE ENTREPRENEUR'S TAKE ON LEADERSHIP, SOCIAL MEDIA, AND SELF-AWARENESS"
askGaryVee.subTitle = "by Gary Vaynerchuk"
var jabJabJabRightHook = Book()
jabJabJabRightHook.thumbnailImageName = "jab_jab_jab_right_hook_book"
jabJabJabRightHook.title = "JAB, JAB, JAB, RIGHT HOOK: HOW TO TELL YOUR STORY IN A NOISY SOCIAL WORLD"
jabJabJabRightHook.subTitle = "by Gary Vaynerchuk"
var theThankYouEconomy = Book()
theThankYouEconomy.thumbnailImageName = "the_thank_you_economy_book"
theThankYouEconomy.title = "The Thank You Economy"
theThankYouEconomy.subTitle = "by Gary Vaynerchuk"
var crushIt = Book()
crushIt.thumbnailImageName = "cursh_it_book"
crushIt.title = "CRUSH IT! WHY NOW IS THE TIME TO CASH IN ON YOUR PASSION"
crushIt.subTitle = "by Gary Vaynerchuk"
return[askGaryVee, jabJabJabRightHook, theThankYouEconomy, crushIt]
}()
func tapBlurButton(sender: AnyObject) {
print("Please Help!")
}
override func viewDidLoad() {
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
navigationItem.title = "Books"
collectionView!.backgroundColor = UIColor.whiteColor()
collectionView?.registerClass(BookCell.self, forCellWithReuseIdentifier:"cellId")
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return books.count
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cellId", forIndexPath: indexPath) as! BookCell
cell.book = books[indexPath.item]
return cell
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let height = (view.frame.width - 16 - 16) * 9 / 16
return CGSizeMake(view.frame.width, height + 16 + 68)
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0
}
}
The easiest solution is to add a clear UIButton on top of your UIImageView and set the frame of your UIButton to be the same as your UIImageView. Then you can use the UIButton's IBAction to send the user to the link.
var tumbnailButton: UIButton = {
let button = UIButton(frame: thumbnailImageView.frame)
button.addTarget(self, action: #selector(tapBlurButton(_:)), for: .touchUpInside)
button.clipsToBounds = true
return button
}()
EDIT:
The above code might throw an error since it is a computed property. Try replacing
var tumbnailButton: UIButton = {
with
var tumbnailButton: UIButton {
and remove the parenthesis at the end.
If that doesn't work, try
var tumbnailButton: UIButton {
get{
let button = UIButton(frame: thumbnailImageView.frame)
button.addTarget(self, action: #selector(tapBlurButton(_:)), for: .touchUpInside)
button.clipsToBounds = true
return button
}
}
Make this class which inherits UITapGestureRecognizer
open class BlockTap: UITapGestureRecognizer {
fileprivate var tapAction: ((UITapGestureRecognizer) -> Void)?
public override init(target: Any?, action: Selector?) {
super.init(target: target, action: action)
}
public convenience init (
tapCount: Int = 1,
fingerCount: Int = 1,
action: ((UITapGestureRecognizer) -> Void)?) {
self.init()
self.numberOfTapsRequired = tapCount
#if os(iOS)
self.numberOfTouchesRequired = fingerCount
#endif
self.tapAction = action
self.addTarget(self, action: #selector(BlockTap.didTap(_:)))
}
open func didTap (_ tap: UITapGestureRecognizer) {
tapAction? (tap)
}
}
then make an extension of UIImageView or UIView
extension UIImageView {
public func addTapGesture(tapNumber: Int = 1, action: ((UITapGestureRecognizer) -> ())?) {
let tap = BlockTap(tapCount: tapNumber, fingerCount: 1, action: action)
addGestureRecognizer(tap)
isUserInteractionEnabled = true
}
}
Then You can use this as
imageView?.addTapGesture(action: {[unowned self] (_) in
//Do whatever on click of image
})
In Your code you can use this as
you can use addTapGesture to any imageview in your code like this
let userProfileImageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "Gary Vee Profile Pic 1")
imageView.layer.cornerRadius = 22
imageView.layer.masksToBounds = true
imageView?.addTapGesture(action: {[unowned self] (_) in
//Code you want to execute on click of Imageview
imageView?.cornerRadius = 4.0
imageView?.clipsToBounds = true
})
return imageView
}()
on click of imageView cornerRadius of image will change to 4.0.