disable/hide UISearchBar when datasource is nil - hide

I want to make sure that no search bar is displayed when the datasource of my table view is empty. (Makes sense, no? shouldn't that be default behaviour?)
Here's a piece of my code that tries (currently uncommented) different things to accomplish that, but somehow it doesn't work.
Can anybody advise me what I'm doing wrong? Let me know if you need more snippets.
messagesArray=loadMessages()
DispatchQueue.main.async {
if (self.messagesArray.count==0){
self.noMessageview.isHidden=false
//self.searchController.searchBar.isHidden = true
//self.searchController.isActive = false
} else{
self.noMessageview.isHidden=true
//self.searchController.searchBar.isHidden = false
//self.searchController.isActive = true
}
self.spinner.stopAnimating()
self.refreshControl.endRefreshing()
self.tableView.reloadData()
}
UPDATE:
I declare the search controller like this:
let searchController = UISearchController(searchResultsController: nil)
and in the ViewDidLoad I do:
navigationItem.searchController = searchController

I believe you are using iOS 11 because of setting UISearchController from navigationItem, Thus you can use the following code to remove it:
if #available(iOS 11.0, *) {
self.navigationItem.largeTitleDisplayMode = .never;
self.navigationItem.searchController = nil
} else {
// Fallback on earlier versions
self.navigationItem.titleView = nil
};
I had some problem and i think its iOS 11 bug, when removing the UISearchController, the view doesn't get adjusted thus i had to call this right before removing UISearchController.
self.navigationItem.largeTitleDisplayMode = .never;
Thats all.

Related

updateSearchResults() not getting called

I have read similar problems and solutions on SO. But none seems to solve my problem. I am using Custom Search Controller and Custom Search Bar and func updateSearchResults(for searchController: UISearchController) is not getting called.
var customSearchController: CustomSearchViewController!
CustomSearchViewController: In ViewDidLoad()
customSearchController = CustomSearchViewController(searchResultsController: ***nil***, searchBarFrame: CGRect(x: 0.0, y: 0.0, width: searchTableView.frame.size.width, height: 44.0), searchBarFont: UIFont(name: "HelveticaNeue", size: 16.0)!, searchBarTextColor: UIColor.purple, searchBarTintColor: UIColor.white)
customSearchController.searchResultsUpdater = self
customSearchController.definesPresentationContext = true
customSearchController.customSearchBar.placeholder = "What are you looking for?"
customSearchController.customSearchBar.backgroundColor = UIColor.white
customSearchController.customSearchBar.sizeToFit()
customSearchController.customSearchBar.resignFirstResponder()
customSearchController.customSearchBar.showsCancelButton = true
customSearchController.customSearchBar.delegate = self
Not getting called: :(
func updateSearchResults(for searchController: UISearchController) {
filtered.removeAll()
filtered = searchArray.filter({ (text) -> Bool in
let tmp: NSString = text as NSString
let range = tmp.range(of: customSearchController.customSearchBar.text!, options: NSString.CompareOptions.caseInsensitive)
return range.location != NSNotFound
})
self.searchTableView.reloadData()
}
After struggling for hours, I was able to solve it by using:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) - UISearchBarDelegate delegate method.
instead of updateSearchResults() - UISearchResultsUpdating delegate method
Hope it helps someone :)
I had to declare UISearchController instance within the class scope. See this answer. https://stackoverflow.com/a/46781890/1511978
Previously I had declared it within the viewDidLoad method
It looks like you did not set this:
searchController.searchResultsUpdater = self
Make sure this is the last command to avoid getting errors. At least this did the job for me.
But maybe your problem was that you call that:
navigationItem.titleView = searchController.searchBar
Instead, you should do that:
navigationItem.searchController = searchController

Build a protobuf object in haskell with optional fields

I am building a PB object in Haskell and I do not want to specify optional fields. Is this possible?
In the very simplest case, I have a header field that has a failure_message that I want empty in most cases. I have some code where a worker task responds with an OK status:
let repMsg = ProtoMsg.WorkerResponse.WorkerResponse {
header = ProtoMsg.ReqResponse.ReqResponse {
ProtoMsg.ReqResponse.status = Just ProtoMsg.Status.OK,
failure_message = Nothing
}
}
Is there a way to set all unspecified fields to Nothing some how? In this case it's not so bad, but when there are more optional fields it gets annoying.
You can make a record value that has the fields you want already set and then update that record.
noFailureMsg = ProtoMsg.ReqResponse.ReqResponse {
failure_message = Nothing
}
let repMsg = ProtoMsg.WorkerResponse.WorkerResponse {
header = noFailureMsg {
ProtoMsg.ReqResponse.status = Just ProtoMsg.Status.OK
}
}
I'm not completely sure this is what you are looking for.

How to use if let with another statement in swift?

If want to both assign a string and check that its not empty in Swift.
if let alternative3Text = attributes.stringForKey("choiceThree") && alternative3Text != "" {
// do stuff with alternative3Text
}
Is this possible in Swift, or do i have to do a nested if-statement?
Update: As of Swift 3 (Xcode 8), additional clauses are
separated by a comma, not by where:
if let alternative3Text = attributes.string(forKey: "choiceThree"),
alternative3Text != "" {
// do stuff with alternative3Text
}
Update: As of Swift 1.2 (Xcode 6.3 beta), you can combine
optional binding with additional conditions:
if let alternative3Text = attributes.stringForKey("choiceThree") where alternative3Text != "" {
// do stuff with alternative3Text
}
Using switch-case still works but is not necessary anymore for this purpose.
Old answer:
It is not possible with an if statement, but with switch.
A switch case can use a where clause to check for additional conditions
(documentation).
Assuming (from your question) that attributes.stringForKey("choiceThree") returns
String?, the following would work:
switch (attributes.stringForKey("choiceThree")) {
case .Some(let alternative3Text) where alternative3Text != "":
// alternative3Text is the unwrapped String here
default:
break
}
No, you can't require additional expressions to be true in an if let statement. You will need to add additional code to do this in either the form of a nested if statement as you've already mentioned, or in some other way. If your only requirement is to keep this statement looking clean and wouldn't mind moving some of the logic elsewhere, you could always make an extension to what ever type your attributes variable is to add this functionality.
Here's an example if attributes was an instance of NSUserDefaults. (just because it already contains a stringForKey() instance method.)
extension NSUserDefaults {
func nonEmptyStringForKey(key: String) -> String? {
let full = self.stringForKey(key)
return full != "" ? full : nil
}
}
And then use it like this
if let alternative3Text = attributes.nonEmptyStringForKey("choiceThree") {
// stuff
}

How to set Excel Import Preferences in InDesign CS6 using extendscript?

This seems like it should be really simple, but for some reason I can't get it to work at all. The following code has no effect whatsoever:
function setExcelImportPrefs() {
with(app.excelImportPreferences){
rangeName = "A1:Z300";
sheetName = "whatever";
tableFormatting = TableFormattingOptions.excelFormattedTable;
}
}
And this doesn't work either:
function setExcelImportPrefs() {
with(app.excelImportPreferences){
app.excelImportPreferences.rangeName = "A1:Z300";
app.excelImportPreferences.sheetName = "whatever";
app.excelImportPreferences.tableFormatting = TableFormattingOptions.excelFormattedTable;
}
}
What am I doing wrong? I've Googled everything, and I'm at my wits end. (Note: I have InDesign CS6, version 8.0)
Edit: Put in a bracket that I accidentally left out when I was copying-and-pasting.
I'm not familiar with these settings, but you seem to have be missing a bracket. Just get rid of the with syntax all together and try
function setExcelImportPrefs() {
app.excelImportPreferences.rangeName = "A1:Z300";
app.excelImportPreferences.sheetName = "whatever";
app.excelImportPreferences.tableFormatting = TableFormattingOptions.excelFormattedTable;
}

Extending or modifying the SharePoint Datasheet view

Has anyone discovered a way to extend or modify the functionality of the SharePoint Datasheet view (the view used when you edit a list in Datasheet mode, the one that looks like a basic Excel worksheet)?
I need to do several things to it, if possible, but I have yet to find a decent non-hackish way to change any functionality in it.
EDIT: An example of what I wish to do is to enable cascading filtering on lookup fields - so a choice in one field limits the available choices in another. There is a method to do this in the standard view form, but the datasheet view is completely seperate.
Regards
Moo
I don't think you can modify it in any non-hackish way, but you can create a new datasheet view from scratch. You do this by creating a new ActiveX control, and exposing it as a COM object, and modifying the web.config file to make reference to the new ActiveX control.
There's an example here:
Creating a custom datasheet control.
Actually, you can do this. Here is a code snippet I stripped out of someplace where I am doing just what you asked. I tried to remove specifics.
var gridFieldOverrideExample = (function (){
function fieldView(ctx){
var val=ctx.CurrentItem[curFieldName];
var spanId=curFieldName+"span"+ctx.CurrentItem.ID;
if (ctx.inGridMode){
handleGridField(ctx, spanId);
}
return "<span id='"+spanId+"'>"+val+"</span>";
}
function handleGridField(ctx, spanID){
window.SP.SOD.executeOrDelayUntilScriptLoaded(function(){
window.SP.GanttControl.WaitForGanttCreation(function (ganttChart){
var gridColumn = null;
var editID = "EDIT_"+curFieldName+"_GRID_FIELD";
var columns = ganttChart.get_Columns();
for(var i=0;i<columns.length;i++){
if(columns[i].columnKey == curFieldName){
gridColumn = columns[i];
break;
}
}
if (gridColumn){
gridColumn.fnGetEditControlName = function(record, fieldKey){
return editID;
};
window.SP.JsGrid.PropertyType.Utils.RegisterEditControl(editID, function (ctx) {
editorInstance = new SP.JsGrid.EditControl.EditBoxEditControl(ctx, null);
editorInstance.NewValue = "";
editorInstance.SetValue = function (value) {
_cellContext = editorInstance.GetCellContext();
_cellContext.SetCurrentValue({ localized: value });
};
editorInstance.Unbind = function () {
//This happens when the grid cell loses focus - hide controls here, do cleanup, etc.
}
//Below I grabbed a reference to the original 'BindToCell' function so I can prepend to it by overwriting the event.
var origbtc = editorInstance.BindToCell;
editorInstance.BindToCell = function(cellContext){
if ((cellContext.record) &&
(cellContext.record.properties) &&
(cellContext.record.properties.ID) &&
(cellContext.record.properties.ID.dataValue)){
editorInstance.ItemID = cellContext.record.properties.ID.dataValue;
}
origbtc(cellContext);
};
//Below I grabbed a reference to the original 'OnBeginEdit' function so I can prepend to it by overwriting the event.
var origbte = editorInstance.OnBeginEdit;
editorInstance.TargetID;
editorInstance.OnBeginEdit = function (cellContext){
this.TargetID = cellContext.target.ID;
/*
. . .
Here is where you would include any custom rendering
. . .
*/
origbte(cellContext);
};
return editorInstance;
}, []);
}
});
},"spgantt.js");
}
return{
fieldView : fieldView
}
})();
(function () {
function OverrideFields(){
var overrideContext = {};
overrideContext.Templates = overrideContext.Templates || {};
overrideContext.Templates.Fields = {
'FieldToOverride' : {
'View': gridFieldOverrideExample.fieldView
}
};
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext);
}
ExecuteOrDelayUntilScriptLoaded(OverrideFields, 'clienttemplates.js');
})();
Also, there are a couple of other examples out there. Sorry, I don't have the links anymore:

Resources