StoryBoard学习(4):presentViewController方法动态显示页面
(1)以modal方式动态显示视图的方法:
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
(2)modal框的关闭方法:
- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
使用 presentViewController 来动态显示一个页面视图。
1.创建一个IOS-Application-Single View Application 项目
2. 在 MainStoryBoard 中增加一个View Controller
对新加的View Controller 设置如下的属性。
注意:这里属性Storyboard Id 设置为 page2 ,在下面的代码中会使用到本属性值。
3. 在原有的视图上添加1个标签和1个按钮(内容分别为 第1页、打开第2页),在新加的视图上添加1个标签和1个按钮(内容分别为第2页、关闭窗口)。
4.设置按钮(打开第2页)的点击事件
分别打开MainStoryBoard 和 ViewController.h窗口,选中按钮(打开第2页),按住“Control”键,用鼠标左键拖拽到ViewController.h的@interface的下一行。
在弹出窗口的Connection属性选择Action,Name属性设置为 openPage2。然后点按钮[Connect]。
可以看到,在ViewController.h中增加了如下代码:
- (IBAction)openPage2:(id)sender;
在ViewController.m中增加了如下代码:
- (IBAction)openPage2:(id)sender { }
修改 ViewController.m中的openPage2方法,具体代码如下:
- (IBAction)openPage2:(id)sender { [self presentViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"page2"] animated:YES completion:nil]; }
OK,到了这一步就可以先编译运行,已经可以点击第1页上的[打开第2页]的按钮,点击后,显示第2页。
接下来,要定义第2页上按钮[关闭窗口]对应的事件。
5. 定义第2页上按钮[关闭窗口]对应的事件
5.1 首先要为第2页创建对应的类文件
鼠标邮件点项目名称,选择New File...
选择 Objective-C class
Subclass选择UIViewController ,Class这里设置为 NewViewController.
5.2 创建了UIViewController类文件后,必须和MainStoryboard中page2对应起来。
打开MainStoryboard,选中 新加的视图,然后修改它的Class属性为 NewViewController。
5.3 定义第2页中按钮[关闭窗口]的事件。
分别打开MainStoryBoard 和 NewViewController.h窗口,选中按钮(关闭窗口),按住“Control”键,用鼠标左键拖拽到NewViewController.h的@interface的下一行。
在弹出窗口的Connection属性选择Action,Name属性设置为 closeIt。然后点按钮[Connect]。
可以看到,在NewViewController.h中增加了如下代码:
- (IBAction)closeIt:(id)sender;
在NewViewController.m中增加了如下代码:
- (IBAction)closeIt:(id)sender { }
修改NewViewController.m中的closeIt方法,具体代码如下:
- (IBAction)closeIt:(id)sender { [self dismissViewControllerAnimated:YES completion:nil]; }
编译运行,点第2页上的按钮[关闭窗口],即能关闭第2页,重新显示第1页。
The code encapsulating a location on an Ellipsoid,
public class GlobalCoordinates implements Comparable<GlobalCoordinates>, Serializable { private double mLatitude; private double mLongitude; public GlobalCoordinates(double latitude, double longitude) { mLatitude = latitude; mLongitude = longitude; } public double getLatitude() { return mLatitude; } public void setLatitude(double latitude) { mLatitude = latitude; } public double getLongitude() { return mLongitude; } public void setLongitude(double longitude) { mLongitude = longitude; } }
Negative latitudes are in the southern hemisphere, and negative longitudes are in the western hemisphere. The Comparable<T> implementation is omitted for clarity.
Now, we start getting to the fun part. The next type encapsulates the “geodetic curve.”
public class GeodeticCurve implements Serializable { private final double mEllipsoidalDistance; private final double mAzimuth; private final double mReverseAzimuth; public GeodeticCurve(double ellipsoidalDistance, double azimuth, double reverseAzimuth) { mEllipsoidalDistance = ellipsoidalDistance; mAzimuth = azimuth; mReverseAzimuth = reverseAzimuth; } public double getEllipsoidalDistance() { return mEllipsoidalDistance; } public double getAzimuth() { return mAzimuth; } public double getReverseAzimuth() { return mReverseAzimuth; } }
A “geodetic curve” is the solution we’re looking for. It describes how to get from one point on an ellipsoid to another. The ellipsoidal distance is the distance, in meters, between the two points along the surface of the ellipsoid. The azimuth is the direction of travel from the starting point to the ending point. The reverse azimuth, of course, is the direction back from the endpoint (which isn’t necessarily a 180 degree turn on an ellipsoid).
The final input to Vincenty’s Formula we need is an ellipsoid. We hold onto four parameters of an ellipsoid: the length of each semi-axis (in meters), the flattening ratio, and the inverse of the flattening ratio. Technically, we only need the length of one semi-axis and any one of the other three parameters. We’ll record all four for convenience.
public class Ellipsoid implements Serializable { private final double mSemiMajorAxis; private final double mSemiMinorAxis; private final double mFlattening; private final double mInverseFlattening; private Ellipsoid(double semiMajor, double semiMinor, double flattening, double inverseFlattening) { mSemiMajorAxis = semiMajor; mSemiMinorAxis = semiMinor; mFlattening = flattening; mInverseFlattening = inverseFlattening; } static public final Ellipsoid WGS84 = fromAAndInverseF(6378137.0, 298.257223563); static public final Ellipsoid GRS80 = fromAAndInverseF(6378137.0, 298.257222101); static public final Ellipsoid GRS67 = fromAAndInverseF(6378160.0, 298.25); static public final Ellipsoid ANS = fromAAndInverseF(6378160.0, 298.25); static public final Ellipsoid Clarke1880 = fromAAndInverseF(6378249.145, 293.465); static public Ellipsoid fromAAndInverseF(double semiMajor, double inverseFlattening) { double f = 1.0 / inverseFlattening; double b = (1.0 – f) * semiMajor; return new Ellipsoid(semiMajor, b, f, inverseFlattening); } public double getSemiMajorAxis() { return mSemiMajorAxis; } public double getSemiMinorAxis() { return mSemiMinorAxis; } public double getFlattening() { return mFlattening; } public double getInverseFlattening() { return mInverseFlattening; } }
Generally, you won’t need to specify ellipsoid parameters. The Ellipsoid type has a number of static instances that define “reference ellipsoids”. Reference ellipsoids represent some organization’s consensus on the “best” ellipsoidal parameters to use to model Earth. Two of the most widely accepted reference ellipsoids are defined above: WGS84 (the 1984 World Geodetic System) and GRS80 (the 1980 Geodetic Reference System).
Finally, we have the class that actually implements Vincenty’s Formula to solve the Geodetic Inverse Problem given a reference ellipsoid and two sets of global coordinates (equation numbers in comments relate directly to Vincenty’s publication):
public class GeodeticCalculator { private final double TwoPi = 2.0 * Math.PI; public GeodeticCurve calculateGeodeticCurve(Ellipsoid ellipsoid, GlobalCoordinates start, GlobalCoordinates end) { // get constants double a = ellipsoid.getSemiMajorAxis(); double b = ellipsoid.getSemiMinorAxis(); double f = ellipsoid.getFlattening(); // get parameters as radians double phi1 = Angle.toRadians(start.getLatitude()); double lambda1 = Angle.toRadians(start.getLongitude()); double phi2 = Angle.toRadians(end.getLatitude()); double lambda2 = Angle.toRadians(end.getLongitude()); // calculations double a2 = a * a; double b2 = b * b; double a2b2b2 = (a2 – b2) / b2; double omega = lambda2 – lambda1; double tanphi1 = Math.tan(phi1); double tanU1 = (1.0 – f) * tanphi1; double U1 = Math.atan(tanU1); double sinU1 = Math.sin(U1); double cosU1 = Math.cos(U1); double tanphi2 = Math.tan(phi2); double tanU2 = (1.0 – f) * tanphi2; double U2 = Math.atan(tanU2); double sinU2 = Math.sin(U2); double cosU2 = Math.cos(U2); double sinU1sinU2 = sinU1 * sinU2; double cosU1sinU2 = cosU1 * sinU2; double sinU1cosU2 = sinU1 * cosU2; double cosU1cosU2 = cosU1 * cosU2; // eq. 13 double lambda = omega; // intermediates we’ll need to compute ’s’ double A = 0.0; double B = 0.0; double sigma = 0.0; double deltasigma = 0.0; double lambda0; boolean converged = false; for (int i = 0; i < 10; i++) { lambda0 = lambda; double sinlambda = Math.sin(lambda); double coslambda = Math.cos(lambda); // eq. 14 double sin2sigma = (cosU2 * sinlambda * cosU2 * sinlambda) + (cosU1sinU2 – sinU1cosU2 * coslambda) * (cosU1sinU2 – sinU1cosU2 * coslambda); double sinsigma = Math.sqrt(sin2sigma); // eq. 15 double cossigma = sinU1sinU2 + (cosU1cosU2 * coslambda); // eq. 16 sigma = Math.atan2(sinsigma, cossigma); // eq. 17 Careful! sin2sigma might be almost 0! double sinalpha = (sin2sigma == 0) ? 0.0 : cosU1cosU2 * sinlambda / sinsigma; double alpha = Math.asin(sinalpha); double cosalpha = Math.cos(alpha); double cos2alpha = cosalpha * cosalpha; // eq. 18 Careful! cos2alpha might be almost 0! double cos2sigmam = cos2alpha == 0.0 ? 0.0 : cossigma – 2 * sinU1sinU2 / cos2alpha; double u2 = cos2alpha * a2b2b2; double cos2sigmam2 = cos2sigmam * cos2sigmam; // eq. 3 A = 1.0 + u2 / 16384 * (4096 + u2 * (-768 + u2 * (320 – 175 * u2))); // eq. 4 B = u2 / 1024 * (256 + u2 * (-128 + u2 * (74 – 47 * u2))); // eq. 6 deltasigma = B * sinsigma * (cos2sigmam + B / 4 * (cossigma * (-1 + 2 * cos2sigmam2) – B / 6 * cos2sigmam * (-3 + 4 * sin2sigma) * (-3 + 4 * cos2sigmam2))); // eq. 10 double C = f / 16 * cos2alpha * (4 + f * (4 – 3 * cos2alpha)); // eq. 11 (modified) lambda = omega + (1 – C) * f * sinalpha * (sigma + C * sinsigma * (cos2sigmam + C * cossigma * (-1 + 2 * cos2sigmam2))); // see how much improvement we got double change = Math.abs((lambda – lambda0) / lambda); if ((i > 1) && (change < 0.0000000000001)) { converged = true; break; } } // eq. 19 double s = b * A * (sigma – deltasigma); double alpha1; double alpha2; // didn’t converge? must be N/S if (!converged) { if (phi1 > phi2) { alpha1 = 180.0; alpha2 = 0.0; } else if (phi1 < phi2) { alpha1 = 0.0; alpha2 = 180.0; } else { alpha1 = Double.NaN; alpha2 = Double.NaN; } } // else, it converged, so do the math else { double radians; // eq. 20 radians = Math.atan2(cosU2 * Math.sin(lambda), (cosU1sinU2 – sinU1cosU2 * Math.cos(lambda))); if (radians < 0.0) radians += TwoPi; alpha1 = Angle.toDegrees(radians); // eq. 21 radians = Math.atan2(cosU1 * Math.sin(lambda), (-sinU1cosU2 + cosU1sinU2 * Math.cos(lambda))) + Math.PI; if (radians < 0.0) radians += TwoPi; alpha2 = Angle.toDegrees(radians); } if (alpha1 >= 360.0) alpha1 -= 360.0; if (alpha2 >= 360.0) alpha2 -= 360.0; return new GeodeticCurve(s, alpha1, alpha2); } } There you have it! You have the tools you need to know the answer to the question “How far is it from here to there?” Here’s an example of using the code to calculate how far it is from the Lincoln Memorial in Washington, D.C. to the Eiffel Tower in Paris: public class Example { static public void main(String[] args) { // instantiate the calculator GeodeticCalculator geoCalc = new GeodeticCalculator(); // select a reference elllipsoid Ellipsoid reference = Ellipsoid.WGS84; // set Lincoln Memorial coordinates GlobalCoordinates lincolnMemorial; lincolnMemorial = new GlobalCoordinates(38.88922, -77.04978); // set Eiffel Tower coordinates GlobalCoordinates eiffelTower; eiffelTower = new GlobalCoordinates(48.85889, 2.29583); // calculate the geodetic curve GeodeticCurve geoCurve = geoCalc.calculateGeodeticCurve( reference, lincolnMemorial, eiffelTower ); double ellipseKilometers = geoCurve.getEllipsoidalDistance() / 1000.0; double ellipseMiles = ellipseKilometers * 0.621371192; System.out.println(“Lincoln Memorial to Eiffel Tower using WGS84″); System.out.printf( ” Ellipsoidal Distance: %1.2f kilometers (%1.2f miles)\n”, ellipseKilometers, ellipseMiles ); System.out.printf(” Azimuth: %1.2f degrees\n”, geoCurve.getAzimuth() ); System.out.printf(” Reverse Azimuth: %1.2f degrees\n”, geoCurve.getReverseAzimuth() ); } }
The library also supports 3-D geodetic calculations (measurements that account for the elevation above or below the reference ellipsoid). For complete source code, documentation, and examples, download the entire Java library.
referencehttp://www.gavaghan.org/blog/2007/11/16/java-gps-receivers-and-geocaching-vincentys-formula/
http://www.gavaghan.org/blog/free-source-code/geodesy-library-vincentys-formula-java/
首先,得准备一张二维码样子的图片,放入指定的位置,需要在这张图片上加入我们的链接地址,看了代码就知道了。 就像我们 买的CRH高铁票上的那种样子,然后就是用的jar包。呵呵,进入正题,自己记录下,若以后自己用到的话,可以节省很大的时间。
package com.zhangjunlin.QRCode; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import com.swetake.util.Qrcode; /** * 二维码生成器 * @blog http://308812025-qq-com.iteye.com/admin/blogs/new * @author Michael */ public class QRCodeEncoderHandler { /** * 生成二维码(QRCode)图片 * @param content * @param imgPath */ public void encoderQRCode(String content, String imgPath) { try { Qrcode qrcodeHandler = new Qrcode(); qrcodeHandler.setQrcodeErrorCorrect('M'); qrcodeHandler.setQrcodeEncodeMode('B'); qrcodeHandler.setQrcodeVersion(7); System.out.println(content); byte[] contentBytes = content.getBytes("gb2312"); BufferedImage bufImg = new BufferedImage(140, 140, BufferedImage.TYPE_INT_RGB); Graphics2D gs = bufImg.createGraphics(); gs.setBackground(Color.WHITE); gs.clearRect(0, 0, 140, 140); // 设定图像颜色> BLACK gs.setColor(Color.BLACK); // 设置偏移量 不设置可能导致解析出错 int pixoff = 2; // 输出内容> 二维码 if (contentBytes.length > 0 && contentBytes.length < 120) { boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes); for (int i = 0; i < codeOut.length; i++) { for (int j = 0; j < codeOut.length; j++) { if (codeOut[j][i]) { gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3); } } } } else { System.err.println("QRCode content bytes length = " + contentBytes.length + " not in [ 0,120 ]. "); } gs.dispose(); bufImg.flush(); File imgFile = new File(imgPath); // 生成二维码QRCode图片 ImageIO.write(bufImg, "png", imgFile); } catch (Exception e) { e.printStackTrace(); } } /** * @param args the command line arguments */ public static void main(String[] args) { String imgPath = "C:/Users/zhangjunlin/Desktop/20110801110720564.png"; String content = "http://308812025-qq-com.iteye.com/admin/blogs/new"; QRCodeEncoderHandler handler = new QRCodeEncoderHandler(); handler.encoderQRCode(content, imgPath); System.out.println("encoder QRcode success"); } }