Pull to Refresh plug-in : PullToBounce Wrapper UIScrollView - ios

I am trying to use this plugin as refresh action : https://github.com/entotsu/PullToBounce
One, issue is I can't understand his explanation.
Explanation given on the github
tableView.frame = yourFrame --> tableView is equal to scrollView.frame in my situation
yourFrame --> I have no idea what it is. The main frame ? Another Frame I have to create ?
bodyView.addSubview(tableViewWrapper) --> bodyView ? Main Frame here ? or Another frame ?
Here is my code for the scrollView for now. Any help on how to implement this plugin using a scrollView made via the storyboard.
class ProfileViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
func makeMock() {
let headerView = UIView()
headerView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 64)
headerView.backgroundColor = UIColor.lightBlue
self.view.addSubview(headerView)
let headerLine = UIView()
headerLine.frame = CGRect(x: 0, y: 0, width: 120, height: 8)
headerLine.layer.cornerRadius = headerLine.frame.height/2
headerLine.backgroundColor = UIColor.whiteColor().colorWithAlphaComponent(0.8)
headerLine.center = CGPoint(x: headerView.frame.center.x, y: 20 + 44/2)
headerView.addSubview(headerLine)
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.blue
let bodyView = UIView()
bodyView.frame = scrollView.frame
bodyView.frame.y += 20 + 44
self.view.addSubview(bodyView)
let tableViewWrapper = PullToBounceWrapper(scrollView: scrollView)
bodyView.addSubview(tableViewWrapper)
tableViewWrapper.didPullToRefresh = {
NSTimer.schedule(delay: 2) { timer in
tableViewWrapper.stopLoadingAnimation()
}
}
makeMock()
}
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
}
One thing, I notice is that there is a View on top of my scrollView that disable me to view it and scroll it. Help here needed please.
Regards,
Hary

Take a look at the Example of this library.
yourFrame is nothing but your tableview class. For example if your tableView Class is named SampleTableView, then it goes like
let tableView = SampleTableView(frame: self.view.frame, style: UITableViewStyle.Plain).
You have to use another class to set up your tableView.

Related

How can I update a UIView width with a UISlider?

I'm trying to change the width of a UIView with a slider. My problem is that instead of updating the views width my code is adding new views. I don't know how to update the view with swift playgrounds.
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
var feelings01Slider: UISlider!
var feelingsWidth01 = 100
var dayFeelings01: UIView!
var dayFeelings02: UIView!
var dayFeelings03: UIView!
override func loadView() {
let view = UIView()
view.backgroundColor = .white
self.view = view
feelings01Slider = UISlider()
feelings01Slider.frame = CGRect(x: 62, y: 375, width: 250, height: 20)
feelings01Slider.minimumValue = 1
feelings01Slider.maximumValue = 248
feelings01Slider.value = 100
feelings01Slider.isContinuous = true
feelings01Slider.addTarget(self, action: #selector(sliderValueDidChange(sender:)), for: .valueChanged)
setUpFeelings()
view.addSubview(feelings01Slider)
}
func setUpFeelings() {
feelingsWidth01 = Int(feelings01Slider.value)
var feelingsX02 = feelingsWidth01 + 62
var feelingsWidth02 = 80
var feelingsX03 = feelingsX02 + feelingsWidth02
var feelingsWidth03 = 70
dayFeelings01 = UIView(frame: CGRect(x: 62, y: 100, width: feelingsWidth01, height: 250))
dayFeelings01.backgroundColor = .yellow
dayFeelings02 = UIView(frame: CGRect(x: feelingsX02, y: 100, width: feelingsWidth02, height: 250))
dayFeelings02.backgroundColor = .blue
dayFeelings03 = UIView(frame: CGRect(x: feelingsX03, y: 100, width: feelingsWidth03, height: 250))
dayFeelings03.backgroundColor = .red
view.addSubview(dayFeelings01)
view.addSubview(dayFeelings02)
view.addSubview(dayFeelings03)
}
#objc func sliderValueDidChange(sender:UISlider) {
feelingsWidth01 = Int(sender.value)
dayFeelings03.removeFromSuperview()
dayFeelings02.removeFromSuperview()
dayFeelings01.removeFromSuperview()
setUpFeelings()
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
I'm new to programming so excuse me if my code seems messy.
You don't need to replace the views with new, differently-sized views . You can just change their frames. Replace your slider selector action with this:
#objc func sliderValueDidChange(sender:UISlider) {
dayFeelings01.frame.size.width = CGFloat(sender.value)
}
Note: because the yellow view was added first, it is expanding underneath the other views. That's why you can't see it get wider. Try changing the order so it's added last and you'll see it. If you want the other views to adjust to the available space, you can update their frames too, a UIStackView might make that easy.
Good luck!

How to add UIView inside a UITableViewCell Programmatically?

I have been creating an app which has a View as that of AppStore (iOS 11) - {Today} view.
Just want to know how do I approach that view. Yet, I think the approach is to create a UIViewController with extensions of UITableViewDataSource and -Delegate, I can get the number of rows and data in my ViewController. And In the dequeReusableCell, I have created a UITableViewCell class in which I have created a UIView Programmatically but that's not working.
class MyTableViewCell: UITableViewCell {
let cellView:UIView = {
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
view.layer.cornerRadius = 15
view.backgroundColor = UIColor.clear
view.layer.shadowColor = UIColor.black.cgColor
view.layer.shadowOpacity = 1
view.layer.shadowOffset = CGSize.zero
view.layer.shadowRadius = 5
return view
}()
}
In the above class snippet, there is no way to insert my UIView in the main view.
There is no method to add views(obviously) because it's under UIViewController rather than UITableViewCell.
So my question is how do I get UIView inside a tableViewCell
Or Is there any other approach to get exact view cells as ios 11 Today tab view? This is what I want ->
I have upgraded my Question, please have a look [here]1: How to nest a UICollectionViewCell inside another one?
You can add customView to uitableviewcell like this.
class MyTableViewCell: UITableViewCell {
let cellView: UIView = {
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
view.layer.cornerRadius = 15
view.backgroundColor = UIColor.white
view.layer.shadowColor = UIColor.black.cgColor
view.layer.shadowOpacity = 1
view.layer.shadowOffset = CGSize.zero
view.layer.shadowRadius = 5
return view
}()
override func awakeFromNib() {
super.awakeFromNib()
addSubview(cellView)
}
}
have a look at this git project this will help you :)
https://github.com/phillfarrugia/appstore-clone

Move UIView from ViewController to Window

Thanks for taking the time to read thus. So basically, I have a UIView in my UIViewController. I want a user to be able to press a button and then the UIView moves from my UIViewController to the my application's window so that the UIView will be above all UIViewControllers. The only thing I could think of doing was
class ViewController: UIViewController {
var window = UIApplication.shared.keyWindow!
var view = UIView()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(view)
}
func tappedAction() {
window.bringSubview(toFront: view)
}
}
but that didn't work. Does anyone have any ideas on how to accomplish this?
You cannot just bring the subview that's in your UIViewController to the front of your UIWindow.
You need to:
Remove the UIView from the UIViewController.
Add the UIView to the main UIWindow.
I chose to do this in this way:
import UIKit
class ViewController: UIViewController {
var customView: UIView!
// Load the main view of the UIViewController.
override func loadView() {
view = UIView()
}
override func viewDidLoad() {
super.viewDidLoad()
// Load the custom view that we will be transferring.
self.customView = UIView(frame: .init(x: 100, y: 250, width: 250, height: 250))
self.customView.backgroundColor = .red
view.addSubview(customView)
// Transfer the view. Call this method in your trigger function.
transfer(self.customView)
}
func transfer(_ view: UIView) {
// Remove the view from the UIViewController.
view.removeFromSuperview()
// Add the view to the UIWindow.
UIApplication.shared.windows.first!.addSubview(view)
}
}
You must set frame fro view at var view = UIView()
then you should add to window window.addSubview(view)
If your view is added on window then window.bringSubview(toFront: view) will work otherwise it will not.
If your view is added on window then you can use bringSubview(toFront:) like that:
Example:
let window = UIApplication.shared.keyWindow!
let view1 = UIView(frame: CGRect(x: window.frame.origin.x, y: window.frame.origin.y, width: window.frame.width, height: window.frame.height))
window.addSubview(view1);
view1.backgroundColor = UIColor.black
let view2 = UIView(frame: CGRect(x: 50, y: 50, width: 100, height: 50))
view2.backgroundColor = UIColor.white
window.addSubview(view2)
UIApplication.shared.keyWindow!.bringSubview(toFront: view1)
So you need to add your view in window:
window.addSubview(view)

Add button overlay on UITableViewController with use static cells

I try to add button overlay on UITableViewController with static cells. But i get this result, button is working, but i not see result of search:
I'm trying to get this result:
I want to button was always at the bottom regardless of scrolling up or down.
In my code i use framework InstantSearch:
import UIKit
import InstantSearch
import WARangeSlider
class SearchTableViewController: UITableViewController {
#IBOutlet weak var resultButton: StatsButtonWidget!
override func viewDidLoad() {
super.viewDidLoad()
resultButton.frame = CGRect(x: 0, y: 0, width: 150, height: 60)
navigationController?.view.addSubview(resultButton)
InstantSearch.shared.registerAllWidgets(in: self.view)
LayoutHelpers.setupResultButton(button: resultButton)
resultButton.addTarget(self, action: #selector(resultButtonClicked), for: .touchUpInside)
}
}
How can i add button overlay on bottom in UITableViewController? Me need use only UITableViewController, not UIViewController with TableView.
You could directly add the button to the UITableView without AutoLayout, and make sure TableView's delegate is the controller, like:
override func viewDidLoad() {
super.viewDidLoad()
self.button.frame = CGRect(x: 0, y: self.tableView.frame.size.height - 50, width: self.tableView.frame.width, height: 50)
self.tableView.addSubview(self.button)
self.tableView.delegate = self
}
Then you are able to fix the button's position by UIScrollView delegate (UITableViewDelegate inherited from this) while TableView is scrolling:
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (scrollView == self.tableView) {
let originY = scrollView.frame.size.height - self.button.frame.size.height + scrollView.contentOffset.y
self.button.frame = CGRect(x: 0, y: originY, width: scrollView.frame.width, height: self.button.frame.size.height)
}
}
Alternatively, if you want to position the button by AutoLayout, just define a NSLayoutConstraint property, and bind it to button's bottom space constraint to its super view. Then adjust the constraint's constant value by same mechanism in scrollViewDidScroll function.
You can just add an view at the bottom of your tableview.
override func viewDidLoad() {
super.viewDidLoad()
addResultButtonView()
}
private func addResultButtonView() {
let resultButton = UIButton()
resultButton.backgroundColor = .red
resultButton.setTitle("Hello", for: .normal)
tableView.addSubview(resultButton)
// set position
resultButton.translatesAutoresizingMaskIntoConstraints = false
resultButton.leftAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.leftAnchor).isActive = true
resultButton.rightAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.rightAnchor).isActive = true
resultButton.bottomAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.bottomAnchor).isActive = true
resultButton.widthAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.widthAnchor).isActive = true
resultButton.heightAnchor.constraint(equalToConstant: 50).isActive = true // specify the height of the view
}

Unable to change contentSize of UIScrollview in WKWebView

I'm trying to add a little bit of extra height to the content of a UIScrollView that is within a WKWebView after it loads by adjusting the contentSize property.
I can modify this property, but it somehow keeps changing back to its original size by the time the next layout/display refresh hits.
To test this even further, I attempted to change contentSize in scrollViewDidScroll. Whenever you scroll to the bottom, you can see for a fraction of a second that it's trying add the extra space and keeps reverting back.
I can't reproduce this issue with UIWebView. It works just fine there. Perhaps some changes were added to WKWebView recently? I'm using Xcode 8 and testing on iOS 9/10.
Given my ineptitude with Dropbox I felt badly so put the attached together to try and help you out. If you change the contentInset property of the WKWebView's scrollView rather than contentSize, this seems to work quite well. I agree with you that while you might be able temporarily to change the content size of the scrollView, it reverts quickly; moreover, there are no delegate methods either for UIScrollView or WKWebView that I can find that you might override to counteract this.
The following sample code has a web page and some buttons that allow you to increase or decrease the top and bottom contentInset and animating you to the appropriate point on the scrollView.
import UIKit
import WebKit
class ViewController: UIViewController {
var webView : WKWebView!
var upButton : UIButton!
var downButton : UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let webFrame = CGRect(origin: CGPoint(x: 100, y: 100), size: CGSize(width: self.view.frame.width - 200, height: self.view.frame.height - 200))
webView = WKWebView(frame: webFrame)
webView.load(URLRequest(url: URL(string: <PUT RELEVANT URL STRING (NB - THAT YOU ARE SURE IS VALID) HERE>)!))
webView.backgroundColor = UIColor.red
webView.scrollView.contentMode = .scaleToFill
self.view.addSubview(webView)
func getButton(_ label: String) -> UIButton {
let b : UIButton = UIButton()
b.setTitle(label, for: .normal)
b.setTitleColor(UIColor.black, for: .normal)
b.layer.borderColor = UIColor.black.cgColor
b.layer.borderWidth = 1.0
return b
}
let upButton = getButton("Up")
let downButton = getButton("Down")
upButton.frame = CGRect(origin: CGPoint(x: 25, y: 25), size: CGSize(width: 50, height: 50))
downButton.frame = CGRect(origin: CGPoint(x: 25, y: 100), size: CGSize(width: 50, height: 50))
upButton.addTarget(self, action: #selector(increaseContentInset), for: .touchUpInside)
downButton.addTarget(self, action: #selector(decreaseContentInset), for: .touchUpInside)
self.view.addSubview(webView)
self.view.addSubview(upButton)
self.view.addSubview(downButton)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func increaseContentInset() -> Void {
guard let _ = webView else { return }
webView.scrollView.contentInset = UIEdgeInsetsMake(webView.scrollView.contentInset.top + 100, 0, webView.scrollView.contentInset.bottom + 100, 0)
webView.scrollView.setContentOffset(CGPoint(x: webView.scrollView.contentInset.left, y: -1 * webView.scrollView.contentInset.top), animated: true)
}
func decreaseContentInset() -> Void {
guard let _ = webView else { return }
webView.scrollView.contentInset = UIEdgeInsetsMake(webView.scrollView.contentInset.top - 100, 0, webView.scrollView.contentInset.bottom - 100, 0)
webView.scrollView.setContentOffset(CGPoint(x: webView.scrollView.contentInset.left, y: -1 * webView.scrollView.contentInset.top), animated: true)
}
}
I hope that helps. If you need an answer based specifically on setting the content size then let me know, but I think this is the best option.

Resources