-1

I have been trying to get this pull to refresh control centered for a while now and I can't seem to get the constraint to work. Am I completely missing something here? I read some tutorials and I read in another question that typically you add position constraints to the parent object. When I tried adding the constraint to the refresh control it told me that it is unable to satisfy constraints.

// Set up the refresh control and add it to the tableView
self.refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
self.refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
self.tableView.addSubview(refreshControl)

// Center the refreshControl
var centerControl: NSLayoutConstraint = NSLayoutConstraint(
 item: refreshControl,
 attribute: NSLayoutAttribute.CenterX, 
 relatedBy: NSLayoutRelation.Equal, 
 toItem: tableView, 
 attribute: NSLayoutAttribute.CenterX, multiplier: 1.0, constant: 1.0)
tableView.addConstraint(centerControl)

EDIT: I attempted to set the size of the refreshControl as was suggested and it still appears off to the right like it is 600 wide like the Any Height Any Width view controller. So apparently trying to set the size has changed nothing

Updated code:

override func viewDidLoad() {
super.viewDidLoad()

// Set tableView delegate and dataSource
tableView.delegate = self
tableView.dataSource = self

// Set up the refresh control and add it to the tableView
self.refreshControl = UIRefreshControl(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: 40))
self.refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
self.refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
self.tableView.addSubview(refreshControl)

// Center the refreshControl
let centerControl: NSLayoutConstraint = NSLayoutConstraint(
  item: refreshControl, 
  attribute: NSLayoutAttribute.CenterX, 
  relatedBy: NSLayoutRelation.Equal, 
  toItem: refreshControl.superview, 
  attribute: NSLayoutAttribute.CenterX, multiplier: 1.0, constant: 0)
refreshControl.superview?.addConstraint(centerControl)

}

Code Update #2: I have tried this and it has not worked either. Am I supposed to have a tableViewController to manage the refreshControl? When I add any of these constraints (even individually) the refresh control gets dragged down with the table. When I don't add constraints it stays put. All I want is to get it so image and text aren't all the way off to the right! Otherwise it works.

override func viewDidLoad() {
super.viewDidLoad()

// Set tableView delegate and dataSource
tableView.delegate = self
tableView.dataSource = self

// Set up the refresh control and add it to the tableView
refreshControl = UIRefreshControl()
refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
tableView.addSubview(refreshControl)
refreshControl.setTranslatesAutoresizingMaskIntoConstraints(false)

// Create the constraints and add them
var constX: NSLayoutConstraint =
  NSLayoutConstraint(item: refreshControl,
                attribute: NSLayoutAttribute.CenterX,
                relatedBy: NSLayoutRelation.Equal,
                   toItem: tableView,
                attribute: NSLayoutAttribute.CenterX,
               multiplier: 1.0, constant: 0)
tableView.addConstraint(constX)

var constW: NSLayoutConstraint =
  NSLayoutConstraint(item: refreshControl,
                attribute: NSLayoutAttribute.Width,
                relatedBy: NSLayoutRelation.Equal,
                   toItem: tableView,
                attribute: NSLayoutAttribute.Width,
               multiplier: 1.0, constant: 0)
tableView.addConstraint(constW)

var constH: NSLayoutConstraint =
  NSLayoutConstraint(item: refreshControl,
                attribute: NSLayoutAttribute.Height,
                relatedBy: NSLayoutRelation.Equal,
                   toItem: nil,
                attribute: NSLayoutAttribute.NotAnAttribute,
               multiplier: 1.0, constant: 50)
tableView.addConstraint(constH)

}
Olyve
  • 701
  • 1
  • 8
  • 27

3 Answers3

1

Try to disable autoresizing mask constraints:

self.refreshControl.setTranslatesAutoresizingMaskIntoConstraints(false)
syfonseq
  • 123
  • 1
  • 6
  • This made the attributed title disappear and did not change the position of the refreshcontrol – Olyve Mar 27 '15 at 00:10
  • Disabling the auto resizing mask conversion is the recommended procedure for making programmatic constraints, even in the Apple docs. Maybe your constraints were interacting with auto-generated constraints and with the auto-generated ones gone you need to make your own constraints work by themselves? Just guessing. Also I've heard that usually it's easier to use the constraint notation language "ASCII art" form when making programmatic constraints. – clearlight Mar 27 '15 at 00:15
  • Hmm I have read differently, and honestly it is the exact same thing constraint wise. There has to be some issue in the way the constraint is being added? I am quite the noob at autolayout :/ – Olyve Mar 27 '15 at 00:23
  • Did you set the size of the refreshControl view using other constraints? – syfonseq Mar 27 '15 at 00:25
  • Nope, the rest of the auto layout is done in the storyboard. Would that be causing the issue with the constraint being set programmatically? – Olyve Mar 27 '15 at 00:26
  • Or I guess if the centerX isn't working would pinning the left and right sides to it's superview's sides work? Though I feel like that isn't the issue – Olyve Mar 27 '15 at 00:30
0

You just have set constraint to center refreshcontrol horizontally with parent.

You also need to set

  1. Top space of refresh control with respect to superview
  2. Width and height of refresh control.
Prajeet Shrestha
  • 7,978
  • 3
  • 34
  • 63
  • That's not how you set the constraints :) refer to this http://stackoverflow.com/questions/26180822/swift-adding-constraints-programmatically. Test various methods of auto-layouting. A good auto-layout skill is must if you are serious about swift . – Prajeet Shrestha Mar 27 '15 at 01:28
  • Okay I am just really really confused I have read over that entire question and nothing I am doing is changing anything with the refreshControl! DO I need to create an instance of a tableViewController to manage it? It is currently in a UIViewController instance with table view – Olyve Mar 27 '15 at 20:33
0

Actually, you don't have to set the frame or constraints of the UIRefreshControl yourself.

You need a UITableViewController and set the refreshControl property with your instance.

Example:

let tableViewController = UITableViewController()
tableViewController.refreshControl = UIRefreshControl()

The TableViewController is responsible of managing the refreshControl: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewController_Class/index.html#//apple_ref/occ/instp/UITableViewController/refreshControl

syfonseq
  • 123
  • 1
  • 6
  • I tried this and adding the tableViewController, setting its tableView to my table, and then adding the refreshControl did nothing :/ the refreshControl is completely gone now – Olyve Mar 27 '15 at 13:15
  • Well actually I had forgotten to initialize it but after initializing it the tableView is moved down from where it was and the refresh control still appears off to the side and not centered – Olyve Mar 27 '15 at 13:19