Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't get table_header_view to work #711

Closed
andrewhavens opened this issue Jul 1, 2015 · 11 comments
Closed

Can't get table_header_view to work #711

andrewhavens opened this issue Jul 1, 2015 · 11 comments

Comments

@andrewhavens
Copy link
Collaborator

I'm looking forward to using this feature. =] I'm trying everything I can think of, but I can't seem to figure out how to use the table_header_view feature on a table screen.

class ListScreen < PM::TableScreen
  title "List"
  stylesheet ListScreenStylesheet

  searchable placeholder: 'Search'
  refreshable

  def table_header_view
    # This is what I'm trying to do, but it doesn't work
    # ListTableHeader.new
    # this is mentioned in the tests, but I can't get this to work either
    UIImageView.alloc.initWithImage(UIImage.imageNamed('test'))
  end
end

What am I doing wrong?

@andrewhavens
Copy link
Collaborator Author

Update: now I'm working on setting the header view manually in the on_load method. Here's what I have so far:

def on_load
  tableView.tableHeaderView = create(MyTableHeader, :table_header)
end

class MyTableHeader < UIView
end

Unfortunately, this still doesn't work...I'm running into this error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RMQ translatesAutoresizingMaskIntoConstraints]: unrecognized selector sent to instance 0x10b8d97c0'

Note that this is a RedPotion app which includes RMQ. Maybe I'm missing something?

/cc @twerth @squidpunch

@twerth
Copy link

twerth commented Jul 5, 2015

That is a rmq command, which means it always returns an rmq object (which is basically an array). This is how you can do chaining. To get the internal object(s), you use .get: create(UILabel).get

We do this kind of thing a lot, so there is shortcut: create!(UILabel)
or `append!(UILabel, :some_style)

@andrewhavens
Copy link
Collaborator Author

Oh, I see. I need to change create to create! because the assignment expects a real UIView object. So I changed it to that, the error went away, but I'm still having trouble appending subviews to my table header.

class MyTableScreen < PM::TableScreen
  def on_load
    tableView.tableHeaderView = create!(MyTableHeader, :table_header)
  end
end

class MyTableHeader < UIView
  def on_load
    apply_style :table_header
    append(UILabel, :label)
  end
end

class MyTableScreenStylesheet < ApplicationStylesheet
  include MyTableHeaderStylesheet
  # ...
end

module ChannelsListTableHeaderStylesheet
  def table_header(st)
    # Style overall view here
    st.frame = {l: 0, t: 0, w: 80, h: 40}
    st.background_color = color.light_gray
  end

  def label(st)
    st.frame = {l: 0, t: 0, w: 80, h: 40}
    st.text = 'hello world'
  end
end

The UILabel never appears.

@andrewhavens
Copy link
Collaborator Author

Thanks to a comment in slack by Steve Kellock, I went back and tried the original ProMotion method, using what I've learned about RMQ. It seems the table_view_header class expects an instance of a UIView, but I also need to apply my styles using RMQ. I made the change and now it works! Here is my fully working example (in case this helps anyone in the future).

class MyTableScreen < PM::TableScreen
  def table_header_view
    create!(MyTableHeader, :table_header)
  end
end

class MyTableHeader < UIView
  def on_load
    append(UILabel, :my_label)
  end
end

class MyTableScreenStylesheet < ApplicationStylesheet
  include MyTableHeaderStylesheet
  # ...
end

module MyTableHeaderStylesheet
  def table_header(st)
    st.frame = {t: 0, l: 0, w: st.superview.bounds.size.width, h: 176}
    st.background_color = color.light_gray
  end

  def my_label(st)
    st.frame = {t: 0, l: 0, w: 100, h: 100, centered: :horizontal}
    st.text = 'hello world'
  end
end

However, this was only part of the problem that I was trying to solve. The real table view that I am trying to add this header to is a "searchable" table view. It seems that this table_view_header method doesn't work when there is a search bar at the top. Does the search bar implement some sort of custom header view? Do I need to append to that view? Or do I need to implement a custom header and reimplement the search functionality in my custom header?

@jamonholmgren
Copy link
Owner

Hey, sorry about the late / non replies, @andrewhavens . Still trying to get caught up from my trip.

I'm spinning up an app to test it right now.

@jamonholmgren
Copy link
Owner

You're right. The UISearchBar is set to the tableHeaderView of the UITableView.

https://github.com/clearsightstudio/ProMotion/blob/master/lib/ProMotion/table/extensions/searchable.rb#L19

Any ideas? I can think of a few solutions, but they seem hacky. Could you show what the end result is supposed to look like?

@andrewhavens
Copy link
Collaborator Author

Here's an example of what I'm ultimately trying to achieve:

screen shot 2015-07-09 at 2 24 09 pm

Notice that the UISegmentedControl (as well as a tappable icon) is above the search bar. Before starting on this, my original thought was that the search bar was somehow part of the view that rendered the table cells, so I thought if I specified a custom table header view, it would appear above the search bar. After some research, I've found that the search bar provides a configuration option that generates a UISegmentedControl, which they refer to as scope buttons. I found a way to specify them:

def on_load
  self.searchDisplayController.searchBar.showsScopeBar = true
  self.searchDisplayController.searchBar.scopeButtonTitles = ['Tab1', 'Tab2']
end

It seems to be a little buggy with the PM implementation of the search bar (clicking on the search bar hides the scope buttons and they won't come back). It would be nice to be able to configure these settings as part of the searchable class method.

Unfortunately, it seems that the scope buttons are intended to be displayed below the search bar, so this might not even work for what I'm trying to do. Maybe I need a custom title bar? One tricky thing is that the design intends to make the header view background semi-transparent so that a background image will show through. Not sure if this is even something that could be configured/styled or if reimplementing a custom search is inevitable.

@jamonholmgren
Copy link
Owner

Ooh, that's really cool! Yes, we should add that to searchable. Something like:

class MyScreen < PM::TableScreen
  title "My Screen"
  searchable placeholder: "Search", scope_bar: [ "Tab1", "Tab2" ]

You can make the background semi-transparent. find() makes it pretty easy to select the header view and then you can do all kinds of things to it.

@silasjmatson might have more thoughts on both the search bar/segment controls (he's working on one right now, although it's Objective-C) and also the blurry background, which he built into an app we built a while back.

@markrickert
Copy link
Contributor

I've done some initial work on supporting scopes but sadly it never got past a barely cobbled together version that barely worked. Certainly not ready for primetime... and it was about a year ago.

@markrickert
Copy link
Contributor

See #509

@andrewhavens
Copy link
Collaborator Author

andrewhavens commented Jul 7, 2016

Closing this since the original topic that this issue was related to (table header view) has been solved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants