How to insert adMob ads after half content? - ios

i made app with my Wordpress Website using rest api in Swift , i have implemented Google AdMob ads in my App, now i want to show AdMob Inline Adaptive Ads to show after half content , this is method i use for split content , i found it on internet
let cont = "This is my content here"
let words = cont.components(separatedBy: " ")
let halfLength = words.count / 2
let firstHalf = words[0..<halfLength].joined(separator: " ")
let secondHalf = words[halfLength..<words.count].joined(separator: " ")
print(firstHalf)
print(secondHalf)
it works fine but i don't know how to insert ad after firstHalf,, can you guys please help me ?
this is the code for inline adaptive banner
let adSize = GADCurrentOrientationInlineAdaptiveBannerAdSizeWithWidth(320)
let bannerView = GADBannerView(adSize: adSize)
bannerView.adUnitID = "ad unit ID"
bannerView.rootViewController = self
let request = GADRequest()
bannerView.load(request)
i have tried to add this code in func and then using something like this
firstHalf + inlineAds() + secondHalf
but it did not work, can we do this ??

If you are using tableView as UI then
1)Create cell contains label
2)Create cell with AdsView
3)Register both cell to table view
4)Create local var items:String
add first and secondString to items array
number of row count of tableView is items.count + 1
In cellforRow in Index method check
if indexPath.row == 1 {
let cell = googleAds cell
return
}
let cell = labelCell
return cell
//Second Option if your UI contains only three items
1)add ScrollView to UI
Add first label to ScrollView
3)Add GoogleAds below firstLabel
Add secondLabel to ScrollView below to GoogleAds View
Set the first and second text

Related

XCUITest unexpected behaviour

I have a simply project with a tableView and a detail vc. The tableView displays 20 rows with "cell (n)" text and the detail view shows a label with the cell pressed.
I want to assert given a tap into a cell i get the text found in the tableView in the detail vc label. So for instance if i tap of the cell 3, which contains "cell 3" i want to get this text, instead of hardcoding it, and assert that i can find this text in the detail vc.
func testCanNavigateToDetailVCWithTheTextFromCell() {
let labelInTableView = app.staticTexts["cell 3"]
labelInTableView.tap()
let labelInDetailVC = app.staticTexts[labelInTableView.label]
XCTAssertTrue(labelInDetailVC.exists)
}
This seems working. But i want to do this:
func testCanNavigateToDetailVCWithTheTextFromCellV2() {
let cell = app.tables.element.cells.element(boundBy: 3) //Get the third cell of the unique tableView
cell.tap()
let textFromPreviousCell = cell.staticTexts.element(boundBy: 0).label //Since is a "Basic" cell it only has one label.
//I will also want to set an accessilibtyIdentifier to the label and access it via cell.staticTexts["id"].label
let labelInDetailVC = app.staticTexts[textFromPreviousCell]
XCTAssertTrue(labelInDetailVC.exists)
}
I set up a project with this issue here
The problem is that you are trying to get the text of the cell after tapping it. This means that the cell is no longer on the screen (the new screen has appeared). All you need to do is change the order of the lines cell.tap() and let textFromPreviousCell = cell.staticTexts.element(boundBy: 0).label. See the new function below:
func testCanNavigateToDetailVCWithTheTextFromCellV2() {
let cell = app.tables.element.cells.element(boundBy: 3) //Get the third cell of the unique tableView
let textFromPreviousCell = cell.staticTexts.element(boundBy: 0).label //Since is a "Basic" cell it only has one label.
cell.tap()
let labelInDetailVC = app.staticTexts[textFromPreviousCell]
XCTAssertTrue(labelInDetailVC.exists)
}

UITableView mess with the rows content

I tried to copy only the necessary code to show my problem. I have a tableview with dynamic content. I created a prototype cell and it has a user name and 10 stars (it's a rating page). People in the group are allowed to rate other people. Everything is working ok, but I have a problem when I scroll down. If I rate my first user with 8 stars, when I scroll down then some user that was in the bottom area of the tableview, appears with the rate that I gave to my first user. I know that tableview reuse cells. I tried many things but with no success. Hope someone can help me on that.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let model = users[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("RatingCell") as! RatingTableViewCell
cell.tag = indexPath.row
cell.playerLabel.text = model.name
cell.averageView.layer.borderWidth = 1
cell.averageView.layer.borderColor = Color.Gray1.CGColor
cell.averageView.layer.cornerRadius = 5
cell.starsView.userInteractionEnabled = true
cell.averageLabel.text = "\(user.grade)"
for i in 0...9 {
let star = cell.starsView.subviews[i] as! UIImageView
star.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(starTap)))
star.userInteractionEnabled = true
star.tag = i
star.image = UIImage(named: (i + 1 <= grade ? "star-selected" : "star-empty"))
}
return cell
}
func changeRating(sender: UIImageView) {
let selectedStarIndex = sender.tag
let cell = sender.superview?.superview?.superview as! RatingTableViewCell
let model = users[cell.tag]
let stars = sender.superview?.subviews as! [UIImageView]
cell.averageLabel.text = "\(selectedStarIndex + 1)"
for i in 0...9 {
let imgName = i <= selectedStarIndex ? "star-selected" : "star-empty"
stars[i].image = UIImage(named: imgName)
}
}
func starTap(gesture: UITapGestureRecognizer) {
changeRating(gesture.view as! UIImageView)
}
The way to solve this problem is by updating the model that holds all the information for the uitableviewcell. Whenever a rating is updated fora particular cell, make sure you reflect that update in the respective object / dictionary in an array. Furthermore, if you have a customuitableviewcell, it might be a good idea to reset the stars in the "prepareForUse" function, so that way when a cell is reused it doesn't use old data.
In your comments, you said that you have an array with selected rates.But you did not show that in your code.
In my opinion, you need record indexPath too, because indexPath.row is binding with your rate data(may be grade?).The best way to do so is that #Jay described up.And you should not write the code of configuring cell data and cell's logic in your view controller.If your business logic is complex, you will find that it is a nightmare.^=^

swift in UI test(test the num of cells in UITable View)

I am very new to UI test. I have an UITableView in my storyboard and it contains some cells.
Update:
I want to assert that the num of cells in UITableView when the app launches will be more than 0. But I don't know how to code this part.Using NSPredicate? Or others?
func testCellsNum()
{
let app = XCUIApplication()
let tableCell = app.tableRows.count
//Then what should I do ?
XCTAssertGreaterThan(tableCell, 0, "should greater than 0")//this line doesn't work
}
If you only have one table:
func testExample() {
let app = XCUIApplication()
let tablesQuery = app.tables
let count = tablesQuery.cells.count
XCTAssert(count > 0)
}
If you have multi tables,using this to get first or any index you want
tablesQuery.elementAtIndex(0).cells

Last line in label for cell wont appear with auto layout and dynamic cell height

I am having some serious trouble getting my multiline label to show all of its lines. Often, the last line of the label simply does not appear, but it is apparent that the dynamically calculated cell height has taken in to account that it should have appeared, leaving around the appropriate amount of white space left over in my cell.
The affected label can display 1-7 lines depending on the data. I have played around with many various constraints to try and get it to display but regardless of what is on the last line, it just won't display.
The weird thing is, sometimes it will display when I segue in to the VC, but then when I use the segmented controller inside the VC to display different data and then go back again, the last line will again not display. The opposite happens frequently too (last line of label cutting off when I segue in to the VC, but then using the segmented controller inside the VC to change the displayed data and then go back, it will then display fine).
Things I have ensured: The label is set to word wrap, has line count of 0, has a height greater than or equal to the height of one of it's lines, its resistance and vertical content hugging is set to the highest of anything in the cell, and the width is set appropriately.
The below code is how I determine how many lines the label will have:
let descString = NSMutableAttributedString()
let bountyStart = NSMutableAttributedString(string: "Bounty: ", attributes: [NSFontAttributeName : UIFont.boldSystemFontOfSize(15)])
let bountyDesc = NSMutableAttributedString(string: bounty.description)
descString.appendAttributedString(bountyStart)
descString.appendAttributedString(bountyDesc)
let bLine = NSMutableAttributedString(string: "\n\n", attributes: [NSFontAttributeName : UIFont.systemFontOfSize(2)])
descString.appendAttributedString(bLine)
if !(bounty.turtles == 0.0){
let turtleStart = NSMutableAttributedString(string: "Your turtle count: ")
let turtleAmount = NSMutableAttributedString(string: bounty.turtleCount.description)
descString.appendAttributedString(turtleStart)
descString.appendAttributedString(turtleAmount)
}
descriptionLabel.attributedText = descString
In the screen shot below, you can see that the height of the cell is being calculated appropriately but for some reason, the last line of the label just refuses to show. It should appear after the "is for noobs" line. I've manipulated the white space to appear after the line instead of elsewhere by setting the problem labels bottom to constraint to be greater than or equal, and all other top to bottom constraints as equal to.
Constraints of the problem label:
I've been stumped for quite a while on this one, and I'm starting to think it's not the constraints I've set but something much deeper. All though I would love to be proven wrong.
Here is my VC code.
import UIKit
class TrendingVC: UIViewController, UITableViewDataSource, UITableViewDelegate{
#IBOutlet weak var menubtn:UIBarButtonItem!
#IBOutlet var trendingTableView:UITableView!
var trendingToggle:Int = 0
let nwt = NWTrending()
let appUserId = NSUserDefaults.standardUserDefaults().stringForKey("UserId") ?? "1" //#TODO: remove ?? 1
var bountyArr: [Bounty] = []
var compArr: [Completion] = []
var peopleArr: [Person] = []
var userId: String = "0"
var username: String = ""
let bountyCellIdentifier = "BountyCellNew"
let personCellIdentifier = "PersonCell"
let completedCellIdentifier = "TrendingCompletedImageCell"
#IBAction func toggleTrending(sender:UISegmentedControl){
switch sender.selectedSegmentIndex{
case 0:
//loads the bounties on segmented control tab
trendingToggle=0
nwt.getTrendingBounties(appUserId, position: 0){(bountyArr, err) in //#TODO: change pos
self.bountyArr = bountyArr as [Bounty]
self.reloadTableViewContent()
}
case 1:
trendingToggle=1
nwt.getTrendingCompletions(appUserId, position: 0){(compArr, err) in
self.compArr = compArr as [Completion]
self.reloadTableViewContent()
}
case 2:
trendingToggle=2
nwt.getTrendingPeople(appUserId, position: 0){(peopleArr, err) in
self.peopleArr = peopleArr as [Person]
self.reloadTableViewContent()
}
default:
break
}
//reloadTableViewContent()
}
override func viewDidLoad() {
super.viewDidLoad()
trendingTableView.estimatedRowHeight = 300.0
trendingTableView.rowHeight = UITableViewAutomaticDimension
/******* Kyle Inserted *******/
//for followers and following back button text, you set it here for when you segue into that section
let backItem = UIBarButtonItem(title: " ", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
navigationItem.backBarButtonItem = backItem
/******* END Kyle Inserted *******/
trendingTableView.allowsSelection = false;
trendingTableView.delegate = self
trendingTableView.dataSource = self
//sidebar code
if self.revealViewController() != nil {
menubtn.target = self.revealViewController()
menubtn.action = "revealToggle:"
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
//loads the bounty on segue
nwt.getTrendingBounties(appUserId, position: 0){(bountyArr, err) in
self.bountyArr = bountyArr as [Bounty]
self.reloadTableViewContent()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//deselectAllRows()
}
func deselectAllRows() {
if let selectedRows = trendingTableView.indexPathsForSelectedRows() as? [NSIndexPath] {
for indexPath in selectedRows {
trendingTableView.deselectRowAtIndexPath(indexPath, animated: false)
}
}
}
func reloadTableViewContent() {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.trendingTableView.reloadData()
println("reloading table view content")
self.trendingTableView.scrollRectToVisible(CGRectMake(0, 0, 1, 1), animated: false)
})
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(trendingTableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if trendingToggle == 0{
return bountyArr.count
}
else if trendingToggle == 1{
return compArr.count
}
else {
return peopleArr.count
}
}
func tableView(trendingTableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if trendingToggle == 0{
return bountyCellAtIndexPath(indexPath)
}
else if trendingToggle == 1{
return completedCellAtIndexPath(indexPath)
}
else{
return personCellAtIndexPath(indexPath)
}
}
//calls method to set and display each trending bounty cell
func bountyCellAtIndexPath(indexPath:NSIndexPath) -> BountyCellNew {
let cell = trendingTableView.dequeueReusableCellWithIdentifier(bountyCellIdentifier) as! BountyCellNew
var bounty = bountyArr[indexPath.row]
cell.setBountyCellTrending(bounty)
return cell
}
func completedCellAtIndexPath(indexPath:NSIndexPath) -> CompletedCell{
let cell = trendingTableView.dequeueReusableCellWithIdentifier(completedCellIdentifier) as! CompletedCell
var comp = compArr[indexPath.row]
cell.setTrendingCompletedCell(comp)
return cell
}
func personCellAtIndexPath(indexPath:NSIndexPath) -> PersonCell{
let cell = trendingTableView.dequeueReusableCellWithIdentifier(personCellIdentifier) as! PersonCell
var peop = peopleArr[indexPath.row]
cell.setTrendingPeopleCell(peop)
return cell
}
}
Unable to comment due to rep low.
This seems like a IB thing, very likely constraints.
Make sure that any component's top constraint placed under this multiline UILabel is set to the bottom of said UILabel.
For example, in this project of mine, both the TitleView and TimeAndDetailsView contain UILabels that span multiplelines. In order to allow autolayout to properly space things all constraints need to be in order, also notice how the top constraint of TimeAndDetails is the bottom of TitleView
Edit note:
Before you tableView.reloadData() type the following 2 lines, or if uncertain, put it inside viewDidLoad
tableView.estimatedRowHeight = 60 //Type your cell estimated height
tableView.rowHeight = UITableViewAutomaticDimensionhere
Went to sleep last night, ok so I decided to add your code to my details label from the storyboards picture I had posted before, and it seems to have displayed just fine. I have a few questions and pointers below.
let descString = NSMutableAttributedString()
let bountyStart = NSMutableAttributedString(string: "Bounty: ", attributes: [NSFontAttributeName : UIFont.boldSystemFontOfSize(15)])
let bountyDesc = NSMutableAttributedString(string: "this would be 'bounty.description and is set to size 40", attributes: [NSFontAttributeName : UIFont.boldSystemFontOfSize(40)])
descString.appendAttributedString(bountyStart)
descString.appendAttributedString(bountyDesc)
let bLine = NSMutableAttributedString(string: "\n\n", attributes: [NSFontAttributeName : UIFont.systemFontOfSize(10)])
descString.appendAttributedString(bLine)
let turtleStart = NSMutableAttributedString(string: "Your turtle count: ")
let turtleAmount = NSMutableAttributedString(string: "random number 1234 goes here")
descString.appendAttributedString(turtleStart)
descString.appendAttributedString(turtleAmount)
detailsLabel.attributedText = descString
Sadly, this is in a scrollview and not in a cell, so there is the first difference. My first question; is your descriptionLabel.attributedText supposed to display different fontscolors or fonttypes/sizes?, if not then I would say to just use descriptionLabel.text instead of descriptionLabel.attributedText.
Now the fact that there is white space but nothing showing us makes me wonder if bounty.turtleCount.description was previously set to color white somewhere else, or you are simply seeing the newlines you added \n\n and nothing is there because if !(bounty.turtles == 0.0) doesnt execute. Are you sure the that if statement is executed? place a breakpoint and follow along to make sure the values are appended to descString
If this is all correct, then my guess would still be on constraints.
Could you elaborate on, quote from you; "sometimes it will display when I segue in to the VC, but then when I use the segmented controller inside the VC to display different data and then go back again, the last line will again not display." what are you doing different in the seg control when loading the values and reloading the tableview that makes it not display, and under what conditions does it work properly when you segue.
I updated xcode and now this doesn't happen anymore.

Trigger an event (tableview reload) whenever a text is in a certain position of a textView in iOS

I just started with iOS programming and I could not find anywhere an answer about this.
I have a Textview, containing a large text divided in paragraphs.
I would like to trigger the reload of a Tableview whenever each paragraph reaches the middle of the TextView.
How could I do it?
Here is the code I wrote so far:
#IBOutlet weak var testo: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
if databaseDB.open() {
// Here I definethe string attributes
var style = NSMutableParagraphStyle()
style.lineSpacing = 15
let font = UIFont(name: "Georgia", size: 18.0) ?? UIFont.systemFontOfSize(18.0)
let textFont = [NSFontAttributeName:font, NSParagraphStyleAttributeName : style]
let fontSuper = UIFont(name: "Georgia-Italic", size: 13.0) ?? UIFont.systemFontOfSize(13.0)
let superFont = [NSFontAttributeName:fontSuper, NSBaselineOffsetAttributeName:6]
// and here the variables
let mainText = NSMutableAttributedString()
var paragraphId : String = ""
// I load the text from a table in the database
let querySQL = "SELECT id, versetext FROM table1"
let results:FMResultSet? = databaseDB.executeQuery(querySQL, withArgumentsInArray: nil)
while results!.next(){
paragraphId = results!.stringForColumn("id")
// I add some other information from another table (here goes also other code, but I have skipped it for simplicity)
let queryDescrSQL = "SELECT paragraph FROM table2 WHERE id = \(paragraphId)"
let paragraphResults:FMResultSet? = databaseDB.executeQuery(queryDescrSQL, withArgumentsInArray: nil)
if paragraphResults?.next() == true {
// here I add the attributes to the text to be shown
let numberParagraph = paragraphResults!.stringForColumn("paragraph")
let paragraphNumber = NSAttributedString(string: numberParagraph, attributes:superFont)
mainText.appendAttributedString(paragraphNumber)
let textParagraph = results!.stringForColumn("versetext")+" "
let paragraphText = NSAttributedString(string: textParagraph, attributes:textFont)
mainText.appendAttributedString(paragraphText)
}
}
databaseDB.close()
// and finally everything is loaded on the TextView
testo.attributedText = mainText
}
}
// I'm letting out the code for the TableView, as it is probably not relevant for the matter
I was thinking of adding some other attribute to paragraphNumber, something like here, but I haven't been able to find how to do it.
Thanks in advance,
Silvo
It's not clear how your paragraphs are divided up (is each in its own UITextView, or do they all form one large text view), but the basics of this are that you need to reload a table view when the scroll view reaches a certain scrolled position.
UITableView has a method reloadData, so call this when your scroll view is at the position.
Scrolling a scroll view just means you are modifying its contentOffset, and the scroll view sends its delegate a message every time the content offset changes. Make your controller the delegate of the scroll view, and implement the scrollViewDidScroll(_:) delegate method. In here, check the current content offset, and if it's at the value you're looking for, reload the table view:
class MyViewController: UIViewController, UIScrollViewDelegate {
// var scrollView = ...
// var tableView = ...
override viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
}
func scrollViewDidScroll(scrollView: UIScrollView) {
// var scrollThreshold = (calculate some scroll threshold based on your paragraph text)
if scrollView.contentOffset.y > scrollThreshold {
tableView.reloadData()
}
}
}

Resources